文章目录
- 一、多态的概述
- 二、多态中成员访问特点 ★
- 三、多态的优势与劣势
- 四、多态下的类型转换
- 4.2 自动类型转换(从子到父)
- 4.2 强制类型转换(从父到子)
- 4.3 instanceof 关键字
一、多态的概述
多态:是指执行同一个行为,会表现出不同的特征。
常见格式:
多态的前提: 有继承 / 实现关系;有父类引用指向子类对象;有方法重写(多态侧重行为多态)。
二、多态中成员访问特点 ★
-
方法调用:编译看左,运行看右
如下面例子:编译的时候是观察 Animal 对象是否有 run 方法,而运行时调用子类的方法。
-
变量调用:编译看左,运行也看左
如下面例子:编译的时候是观察 Animal 对象是否有 name 变量,并且运行时调用的也是父类的变量。
public abstract class Animal {public String name = "动物";public abstract void run(); } public class Dog extends Animal{public String name = "狗狗";@Overridepublic void run() {System.out.println("狗在跑~~");} } public class Tortoise extends Animal {public String name = "乌龟";@Overridepublic void run() {System.out.println("乌龟在跑~~");} }
public class Test {public static void main(String[] args) {Animal dog = new Dog();dog.run(); // 狗在跑~~System.out.println(dog.name); // 动物Animal tortoise = new Tortoise();tortoise.run(); // 乌龟在跑~~System.out.println(tortoise.name); // 动物} }
注:多态注重行为多态。
三、多态的优势与劣势
在多态形式下,右边对象可以实现解耦合,便于扩展和维护。
Animal a = new Dog();
a.run(); // 后续业务行为随对象而变,后续代码无需修改
定义方法的时候,使用父类型作为参数,该方法就可以接收这父类的一切子类对象,体现出多态的扩展性与便利。
public class Test {public static void main(String[] args) {Animal dog = new Dog();Animal tortoise = new Tortoise();run(dog); // 狗在跑~~run(tortoise); // 乌龟在跑~~}public static void run(Animal animal){animal.run();}
}
多态下会产生一个问题:多态下不能使用子类的独有功能,因此可利用强制类型转换解决此问题。
四、多态下的类型转换
4.2 自动类型转换(从子到父)
子类对象赋值给父类类型的变量指向。
4.2 强制类型转换(从父到子)
格式:子类 对象变量 = (子类)父类类型的变量
作用:可以解决多态下的劣势,可以实现调用子类独有的功能。
注意:如果转型后的类型和对象真实类型不是同一种类型,那么在转换的时候就会出现类型转换异常 ClassCastException。
4.3 instanceof 关键字
Java 建议强转前使用 instanceof
判断当前对象的真实类型,再进行强制转换。
判断关键字左边的变量指向的对象的真实类型,是否是右边的类型或者是其子类类型,是则返回 true,反之返回 false。
例1:调用子类独有功能。
public class Animal {public String name = "动物";public void run(){System.out.println("动物可以跑~~");}
}
public class Dog extends Animal {public String name = "狗狗";@Overridepublic void run() {System.out.println("狗在跑~~");}/**独有功能*/public void lookDoor(){System.out.println("狗在看门!");}
}public class Tortoise extends Animal {public String name = "乌龟";@Overridepublic void run() {System.out.println("乌龟在跑~~");}/**独有功能*/public void layEggs(){System.out.println("乌龟在下蛋!");}
}
public class Test1 {public static void main(String[] args) {// 自动类型转换Animal a = new Dog();a.run();// a.lookDoor(); // 多态下无法调用子类独有功能// 强制类型转换:可以实现调用子类独有功能的// 规定:有继承或者实现关系的 2 个类型就可以强制类型转换,运行时可能出现问题。// Tortoise t = (Tortoise) a; // 报错。编译阶段可以强制执行不会出错,运行时可能会出错Dog d = (Dog) a; // 因为 a 可能不是 Dog,可能是 Tortoise,因此需要强转d.lookDoor();// 建议强制转换前,先判断变量指向对象的真实类型,再强制类型转换。if(a instanceof Tortoise){Tortoise t = (Tortoise) a;t.layEggs(); // 调用子类独有的功能}else if(a instanceof Dog){Dog d1 = (Dog) a;d1.lookDoor();}}
}
例2:多态作为参数的实例。
public class Test2 {public static void main(String[] args) {Animal a1 = new Dog();go(a1);}public static void go(Animal a){System.out.println("预备~~~");a.run();// 独有功能if(a instanceof Tortoise){Tortoise t = (Tortoise) a;t.layEggs();}else if(a instanceof Dog){Dog d1 = (Dog) a;d1.lookDoor();}System.out.println("结束~~~~");}
}
文章参考:Java入门基础视频教程,java零基础自学就选黑马程序员Java入门教程(含Java项目和Java真题)