Java基础提高篇(二)多态

来源:互联网 发布:windows网络监控工具 编辑:程序博客网 时间:2024/06/08 05:43

在面向对象的程序设计语言中,多态是继数据抽象和继承之后的第三种特征。

不同类的对象对同一消息作出不同的响应就叫做多态。

多态存在的三个条件

1、有继承关系  

2、子类重写父类方法  

3、父类引用指向子类对象

多态方法调用允许一种类型表现出与其他相似类型之间的区别,只要它是从同一基类导出而来的,这种区别是根据方法行为的不同而表现出来的,虽然这些方法都可以通过同一个基类来调用。

看一个简单的多态例子

enum Ball{    BASKETBALL,FOOTBALL}class Sport{    public void play(Ball ball){        System.out.println("Sport------"+ball);    }}class BaskSport extends Sport{    @Override    public void play(Ball ball) {        System.out.println("BaskSport-------"+ball);    }}public class Demo1 {    public static void p(Sport s){        s.play(Ball.BASKETBALL);    }public static void main(String[] args) {        BaskSport baskSport=new BaskSport();        p(baskSport);    }}

输出: BaskSport——-BASKETBALL

Demo1.p()接收一个Sport引用,同时也可以接收任何Sport的导出类,当将BaskSport引用传递给p()时,由于这是向上转型,是允许的,向上转型可能会缩小接口,但不会比父类的全部接口更窄。

多态的二个缺陷

1.“覆盖”私有方法
public class Demo1 {private void fun(){    System.out.println("Demo1的私有fun方法");}   public static void main(String[] args) {        Demo1 demo1 = new Zi();        demo1.fun();    }}class Zi extends Demo1{    public void fun(){        System.out.println("Zi的fun方法");    }}

输出:Demo1的私有fun方法

按道理,应该输出”Zi的fun方法”才对,但是这里有个陷阱就是Demo1的fun方法是私有的,无法被覆盖,而Zi类中的fun是新的方法。所以:只有非private方法才可以被覆盖。

2.域和静态方法

只有普通方法的调用可以是多态的,域和静态方法不能是多态的。

class NBA{    public String location="USA";    public void f(){        System.out.println(location);    }}class CBA extends NBA{    public String location="CBA";    public void f(){        System.out.println(location);    }}public class Demo1 {public static void main(String[] args) {         NBA nba = new CBA();         String location = nba.location;         System.out.println(location);         nba.f();    }}

输出:

USACBA

可以看到,当子类对象转型为父类引用时,任何域访问操作都将由编译器解析,因此不是多态的。其实在实际开发过程中,我们不会将域设置为public的,一般设置成private,因此不能直接访问它们,只能通过调用方法访问。

如果某个方法是静态的,它的行为就不具有多态性

class NBA{    public static void f1(){        System.out.println("NBA");    }    public void f2(){        System.out.println("NBA----f2");    }}class CBA extends NBA{    public static void f1(){        System.out.println("CBA");    }    public void f2(){        System.out.println("CBA----f2");    }}public class Demo1 {public static void main(String[] args) {        NBA nba = new CBA();        nba.f1();        nba.f2();    }}

输出:

NBACBA----f2

**
静态方法是与类,而非与单个对象相关联的。**

向下转型

class NBA{    public void f1(){}}class CBA extends NBA{    public void f1(){}    public void f2(){}}public class Demo1 {public static void main(String[] args) {        NBA nba = new NBA();        nba.f1();        ((CBA)nba).f2();    }}

重点是这句:((CBA)nba).f2();

如果单纯的nba.f2();那么无法编译,因为NBA类并没有f2()方法,所以必须进行向下转型,转换为CBA类型的,因为CBA类型有f2()。

向上转型和向下转型其实很好理解,小的—>大的,大的—>不能说是小的。毕竟中国是上海的,这句话要被笑话的。

友情链接:
谈谈多态

0 0