什么是多态?
多态是在继承/实现情况下一种现象,表现为:对象多态和行为多态。
同一个对象,在不同时刻表现出来的不同形态。
多态的前提:
要有继承/实现关系
要有方法的重写
要有父类引用指向子类对象。
多态的具体代码体现:
People类:
package cn.ensource.d1_polymorphism;
// 父类
public class People {
public void run() {
System.out.println("人类快跑");
}
}
Teacher类:
package cn.ensource.d1_polymorphism;
public class Teacher extends People{
@Override
public void run() {
System.out.println("老师快跑!");
}
}
Student类:
package cn.ensource.d1_polymorphism;
public class Student extends People{
@Override
public void run() {
System.out.println("学生快跑!");
}
}
Test类:
package cn.ensource.d1_polymorphism;
public class Test {
public static void main(String[] args) {
// 目标:认识对象多态、行为多态
// 对象多态
People p1 = new Teacher();
People p2 = new Student();
// 行为多态
p1.run(); // 编译看左边,运行看右边,看真实对象的方法
p2.run();
}
}
多态的一个注意事项:
多态对对象、行为的多态,Java中的属性(成员变量)不谈多态。
package cn.ensource.d1_polymorphism;
public class Test {
public static void main(String[] args) {
// 目标:认识对象多态、行为多态
// 对象多态
People p1 = new Teacher();
People p2 = new Student();
// 行为多态
p1.run(); // 编译看左边,运行看右边,看真实对象的方法
p2.run();
System.out.println(p1.name); // 识别技巧:编译看左边,运行看左边,变量不讲多态性
System.out.println(p2.name);
}
}
多态中成员访问特点(记忆):
成员访问特点:
成员变量:编译看父类,运行看父类;
成员方方法:编译看父类,运行看子类;
多态使用的好处:
在多态的形式下,右边对象是解耦合的,更便于扩展和维护。
高内聚、低耦合。
定义方法的时候,使用父类类型的形参,可以接受一切子类对象,扩展性强,更便利。
提高了程序的扩展性,定义方法的时候,使用父类型作为参数,在使用的时候,使用具体的子类型参与操作。
弊端:不能使用子类特有的成员。
package cn.ensource.d2_polymorphism;
public class Test {
public static void main(String[] args) {
// 目标:认识多态的好处
//好处一:可以实现解耦合,右边对象可以随时切换,后续业务随机改变
// People p1 = new Student();
People p1 = new Teacher();
p1.run();
// 好处二: 可以使用父类类型的变量作为形参,可以一切子类对象
Student s = new Student();
Teacher t = new Teacher();
}
public static void go(People p) {
}
}
多态下,会存在一个问题,怎么解决?
多态下不能使用子类的独有功能。
package cn.ensource.d2_polymorphism;
public class Test {
public static void main(String[] args) {
// 目标:认识多态的好处
//好处一:可以实现解耦合,右边对象可以随时切换,后续业务随机改变
// People p1 = new Student();
People p1 = new Teacher();
p1.run();
// p1.test(); // 无法调用子类的独有功能,因为编译时看左边,人类是没有这个方法的。
// 好处二: 可以使用父类类型的变量作为形参,可以一切子类对象
Student s = new Student();
Teacher t = new Teacher();
}
public static void go(People p) {
}
}
多态下的类型转换问题:
类型转换:
自动类型转换: 父类 变量名 = new 子类();
强制类型转换:子类 变量名 = (子类)父类变量;
强类型转换的一个注意事项:
存在继承/实现关系就可以在编译阶段进行强制类型转换,编译阶段不会报错。
运行时,如果发现对象的真实类型与强制后的类型不同,就会报类型转换异常(ClassCastException)的错误出来。
Exception in thread "main" java.lang.ClassCastException: class cn.ensource.d2_polymorphism.Student cannot be cast to class cn.ensource.d2_polymorphism.Teacher (cn.ensource.d2_polymorphism.Student and cn.ensource.d2_polymorphism.Teacher are in unnamed module of loader 'app')
at cn.ensource.d2_polymorphism.Test.main(Test.java:19)
强转前,Java建议:
使用instanceof关键字,判断当前对象的真实类型,再进行强转。
对象回调。
多态中的成员转型:
向上转型:
父类引用指向子类对象就是向上转型。
向下转型:
格式:子类 对象名 = (子类型)父类引用。