[03] 多态


1、多态的定义

多态的含义是,对外是一种表现形式,内在有多种具体的实现。在面向对象的程序设计理念中,多态性的定义在于,同一操作作用于不同类的实例,将产生不同的执行结果。

多态在Java中的体现为:
  • 方法重载
  • 方法覆盖
  • 运行时多态

根据定义,前两者的体现也是显而易见了,方法重载的方法名都是一个,但是根据参数不同调用时候实现也不同;方法覆盖也同理,方法名和父类方法相同,但是调用时调用的子类的新的实现。

而这里主要说明的是 “运行时多态”,它的体现主要在于,定义的某个引用变量,在调用其方法时具体调用哪个类(在编译时)是不确定的,在运行时才确定



2、向上转型

//父类
public class Animal { 
    
    public void eat() {
        System.out.println("animal eat");
    }

}

//子类
public class Cat extends Animal{

    public void eat() {
        System.out.println("cat eat");
    }
 
    
    public void run() {
        System.out.println("cat run");
    }

}

我们说,在继承关系中是“is a”的关系,像Cat继承了Animal,那么new Cat()既可以说它是猫,也可以说它是动物,所以如下两种声明都是不会编译出错的:
Cat cat1 = new Cat();
Animal cat2 = new Cat();

这种子类定义为父类的引用,我们称之为自动类型提升,也叫向上转型。向上转型的好处在于,可以提高程序的扩展性

假如我现在有方法 method(Animal animal) { animal.eat(); } 这意味着不论是Cat、Dog都可以作为参数,这可比对应着写两个方法 method(Cat cat){ cat.eat(); } 和 method(Dog dog){ dog.eat(); } 好多了,更何况,假如还有Bird、Pig等等呢?别被累坏了。

2.1 cat2.eat()

但是这种方式在调用方法时,就涉及到了新的问题,Animal cat2 = new Cat(); 那么 cat2.eat() 到底执行的是父类Animal的eat方法,还是子类中的eat方法呢?

Java支持运行时多态,即究竟执行Animal的eat还是Cat的eat,是在运行时才确定的。程序运行时,Java从实例所属的类开始寻找匹配的方法执行,如果当前类没有匹配的方法,就沿着继承关系逐层向上寻找执行

所以这里执行的是Cat的eat,除非子类没有覆盖,才会调用Animal的eat。

需要注意的是,这种运行多态对静态方法是不适用的,假如Animal和Cat的eat都是静态方法,那么cat2调用eat实际上也是调用的Animal的eat。对于属性也是一样,属性是不存在所谓覆盖的,所以在利用引用访问对象的属性或静态方法时,是引用类型决定了实际上访问的是哪个属性,而非实际代表的类

2.2 cat2.run()

那么这样一来,假如我想执行Cat类的run方法,我可以这样执行吗? cat2.run(); 

很遗憾,不行。因为在编译时,编译器是把变量当成你声明的类去认知的,也就是说它会到Animal类中寻找是否有run方法,实际上Animal中并没有定义,所以这里编译会出错,程序无法执行。



3、向下转型

在cat2.run()我们提到,编译时,其类型被视为父类,所以为了保证编译通过也只能调用父类的属性和方法,然而如此一来子类中扩展了的新的内容就无法使用,很多时候这种情况是无法满足我们的需要的。

所以我们可以对实例进行强制转换,即向下转型。这样就可以使用子类中特有的方法。

Animal cat2 = new Cat();
Cat cat3 = (Cat)cat2;
cat2.run();



4、instanceof

instanceof 运算符是用来在运行时判断对象是否是指定类的一个实例。返回值为boolean值,如果对象不是指定类的一个实例,或者对象是null,则返回false。

public class Test {
    public static void main(String[] args) {
        Animal cat2 = new Cat();
        if (cat2 instanceof Cat) {
            ((Cat) cat2).run();
        }
    }
}


posted @ 2017-09-01 10:15  Dulk  阅读(275)  评论(0编辑  收藏  举报