1.什么是Java多态的概念
面向对象程序设计的三大支柱是封装、继承和多态。
继承关系使一个子类能继承父类的特征,并且附加一些新特性。子类是它的父类的特殊化,每个子类的实例都是其父类的实例,但是反过来不成立。因此总可以将子类的实例传递给需要父类型的参数。使用父类对象的地方都可以使用子类的对象,这就是通常所说的多态(polymorphism)。简单来说,多态意味着父类型的变量可以引用子类型的对象。
2.实现多态的条件:
(1)继承:必须有子类继承父类的关系。
(2)方法重写:方法重写发生在具有继承关系的不同类中,子类会重写父类中的一些方法,调用方法时就会调用子类重写的方法而非父类的方法。
(3)向上转型(upcasting):在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够调用父类的方法和子类的方法。
实例class Shape {
void draw() {}
}
class Circle extends Shape {
void draw() {
System.out.println("Circle.draw()");
}
}
class Square extends Shape {
void draw() {
System.out.println("Square.draw()");
}
}
class Triangle extends Shape {
void draw() {
System.out.println("Triangle.draw()");
}
}
3.向上转型
(1)概念:把不同的子类对象都当作父类来看,进而屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,统一调用标准。
(2)例如:Parent a = new Child();
*注意:
(1)子类对象看作父类对象,只能调用父类的功能,不能调用子类自己的方法,
(2)如果子类重写了父类中声明过的方法,方法体执行的就是子类重写过后的功能,但是其他资源使用的还是父类型的。
(3)向上转型不要强制转型。
4.向下转型
概念:子类的引用指向子类对象,过程中必须要采取到强制转型,这个是之前向上转型过的子类对象仍然想执行子类的特有功能,所以要重新恢复成子类对象。
Parent a = new Child();//向上转型,此时a是Parent类型
Child c = (Child)a;//此时,把Parent类型的a转成小类型Child
*注意:相当于创建了一个子类对象,可以用父类的,也可以用自己的,向下转型时,是为了方便使用子类的特殊方法,当子类方法做了功能拓展,就可以直接使用子类功能。
向下转型必须要在向上转型之后
5.动态绑定:
动态绑定与多态:
多态是动态绑定的使用,动态绑定是多态的实现原理。
动态绑定的工作机制如下:
假设对象o是类C1,C2,…,Cn-1,Cn的实例,其中C1是C2的子类,C2是C3的子类,…,Cn-1是Cn的子类。也就是说,Cn是最通用的类,C1是最特殊的类。在Java中,Cn是Object类。如果对象o调用一个方法p,那么JVM会依次在类C1,C2,…,Cn-1,Cn中查找方法p的实现,直到找到为止。一旦找到一个实现,就停止查找,然后调用这个首先找到的实现。
6.抽象类与抽象方法:
(1)概念:抽象类用来描述一种类型应该具备的基本特征和功能,具体如何去完成这些行为由子类通过方法重写来完成,抽象方法只有功能声明,没有功能主体实现的方法,具有抽象方法的类一定为抽象类。
(2)定义:在Java语言中通过abstract关键词定义抽象类与抽象方法
一个抽象方法只有方法头,没有方法主体。
访问修饰符 abstract 返回类型 方法名(参数列表);
例如:public abstract void getArea();
抽象类:
例如:public abstract class 类名
(3)注意:
包含抽象方法的类就会自动变成抽象类,因此必须通过以abstract关键字声明。
如果派生类没有重写抽象方法,编译器会报错。
抽象方法被用来确保派生类会实现这个方法。
抽象类可以含零至多个普通方法,也可以含零至多个抽象方法。
不论抽象类是否含抽象方法,其都不允许实例化,即不能创建抽象类的对象,因为其描述的是抽象概念。它只能作为其他类的基类。
若父类为抽象类,且子类不想成为抽象类,则子类必须将父类中所有的抽象方法均重写为带方法体的普通方法,否则子类仍必须为抽象类。
参考文献:梁勇. Java语言程序设计与数据结构基础篇[M]. 北京:机械工业出版社,2018.167-175