博客原文 ----> https://www.yanzhaochang.top/read?b_id=6
Java 多态总结
1 定义
指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)
多态,简而言之就是同一个行为具有多个不同表现形式或形态的能力。
比如说,有一杯水,我不知道它是温的、冰的还是烫的,但是我一摸我就知道了。我摸水杯这个动作,对于不同温度的水,就会得到不同的结果。这就是多态。
2 动态链接
当父类中的一个方法只有在父类中定义而在子类中没有重写的情况下,才可以被父类类型的引用调用;
对于父类中 定义的方法,如果在子类中进行了重写,那么父类类型的引用将会调用子类中的方法这种就是动态链接
3 实现的必要条件
继承、重写、向上转型
继承:在多态中必须存在有继承关系的子类和父类。
重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。
向上转型:父类的引用指向子类的对象
转型:
向上转型:为了限制子类特有功能的访问 Animal a = new Cat();
可以调用父类类型中的所有成员,不能调用子类类型中特有成员;最终运行效果看子类的具体实现!
向下转型:为了使用子类中的特有功能 Animal a = new Cat() Cat c = (Cat)a;强制转换;
1:只能强转父类的引用,不能强转父类的对象
2:要求父类的引用必须指向的是当前目标的对象
3:可以调用子类类型中的所有的成员。
4:属性没有重写
4 多态的好处
1 可替换性:多态对已经存在的代码具有可替代性。图形类可以对应圆类,对其他任何圆形几何体,如圆环,也同样工作。
2 可扩充性:多态对代码增加可扩充性。增加新的子类不影响已经存在类的多态性、继承性,以及其他特性的运行。
3 接口性:多态是超类通过方法签名,向子类提供一个公共的接口,由子类来完善或者覆盖她而实现。
4 维护性:有利于后期代码的维护。
5 多态的弊端
1 不能使用子类的特有功能
2 创建子类调用
6 多态编译运行总结
1 成员变量:编译看左边,运行看左边
2 构造方法:创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化。
3 成员方法:编译看左边,运行看右边(方法重写的意义)
4 静态方法:编译看左边,运行看右边。静态和类相关,算不上重写,所以还是访问的左边
7 总结
1 使用父类类型的引用指向子类的对象
2 该引用只能调用父类中定义的方法和变量
3 如果子类中重写了父类的一个方法,那么在调用这个方法的时候,就会调用子类的这个方法(动态链接,动态调用)
4 变量不能够被重写,重写的概念只针对于方法,如果在子类中重写了父类的变量,在编译时就会进行报错。
例:
abstract class Animal {
abstract void say();
}
class Dog extends Animal {
void say() {
System.out.println("汪汪汪!");
}
void lookHome() {
System.out.println("看家");
}
}
class Cat extends Animal {
void say() {
System.out.println("喵喵喵");
}
void catchMouse() {
System.out.println("抓老鼠");
}
}
class DTDemo {
public static void main(String[] args) {
Animal a = new Cat();
/* 自动类型提升,猫对象提升了动物类型。但是猫的特有功能无法访问
作用就是限制对特有功能的访问。
专业讲:向上转型。将子类型隐藏。就不用使用子类的特有方法。*/
// a.catchMouse(); //编译报错误: 找不到符号。
/*如果还想用具体动物猫的特有功能。
你可以将该对象进行向下转型。*/
// Cat c = (Cat)a;//向下转型的目的是为了使用子类中的特有方法。
// c.say();
// c.catchMouse();
// 注意:对于转型,自始自终都是子类对象在做着类型的变化,并且有继承关系。
// Animal a1 = new Dog();
// Cat c1 = (Cat)a1;//编译报错误: ClassCastException
}
}