1、对象的多态性
核心内容为:Java对象的向上转型机制
(1)例1:
class Person{public void print(){System.out.println("1.Person类的print方法");}}class Student extends Person{public void print(){System.out.println("2.Student类的print方法");}}public class Text1{public static void main(String[] args){Person per = new Student();//向上转型per.print();}}//运行结果://2.Student类的print方法
Java中使用了向上转型机制,实现对象的多态性,通过父类对象的引用指向子类对象,即可直接调用子类对象重写的方法。
(2)例2:
//参数统一化class Person{public void print() {System.out.println("1.Person类的print方法");}}class Student extends Person{public void print(){System.out.println("2.Student类的print方法");}}class Worker extends Person{public void print(){System.out.println("3.Worker类的Print方法");}}public class Text2{public static void main(String[] args){fun(new Person());//Person per = new Person();fun(new Student());//Person per = new Student();//向上转型 Student类 转为 Person类fun(new Worker());//Person per = new Worker();//向上转型 Worker 类 转为 Person类}public static void fun(Person per){per.print();}}//运行结果://1.Person类的print方法//2.Student类的print方法//3.Worker类的Print方法
向上转型的核心在于使用哪个类型的构造器new的空间并且调用方法是否被重写。
向下转型机制有安全隐患不建议使用。
2、方法的多态性
多态分成两类
(1)前期绑定(方法重载)
又称为编译时多态。
class Person{public void say(){}public void say(String s){}public void say(String s1, String s2){}}
类似于C++的静态多态。
(2)后期绑定(方法重写)
又称为动态绑定/运行时绑定。
触发的三个必要条件:
- 继承
- 方法重写
- 父类引用指向子类对象
子类Student重写了父类Person的方法print(),父类对象的引用per指向子类对象Student(),调用per的print()方法时实际上使用的是Student的print()。运行时才知道per要绑定的是Student对象。class Person{public void print(){System.out.println("1.Person类的print方法");}}class Student extends Person{public void print(){System.out.println("2.Student类的print方法");}}public class Text1{public static void main(String[] args){Person per = new Student();//向上转型per.print();}}//运行结果://2.Student类的print方法
缺陷:
(1)私有方法覆盖问题
私有方法无法覆盖因此不能实现重写,此时实现多态会失败,依然执行的是父类的私有方法。要小心父类的私有方法不能跟子类的方法重名。
(2)域和静态方法
方法调用时只能使用普通的调用,super之类的其他调用会使得多态失败。
3、构造器和清理的多态性
(1)构造器复用类中已提及,构造器连接从子类开始向上链接,运行时从根父类开始向下允许每一层构造器。
(2)清理
子类的清理方法必须调用父类的清理方法,然后再单独清理子类的内容,否则会出现父类内容未清理的情况。
4、协变返回类型
多态实现的同时,方法的返回值类型type可以被改变,此时,父类对象引用调用方法时,返回值的类型可以是type也可以是type的子类。
package Animal;public class CovariantDemo {public static void main(String[] args) {Animal animal=new Animal();Food food=animal.behavior();food.eat();Dog dog=new Dog();Bone bone=dog.behavior();bone.eat();}}//基类class Animal{public Food behavior(){System.out.println("Animal:");return new Food();}}//子类class Dog extends Animal{@Overridepublic Bone behavior(){System.out.println("Dog:");return new Bone();}}class Food{public void eat(){System.out.println("Animal like to eat food");}}class Bone extends Food{@Overridepublic void eat(){System.out.println("Dogs like to eat bones");}}
这基于里氏替换原则:任何父类可以出现的地方,子类也可以出现。
