目录
3.多态下引用数据类型的类型转换(实现在多态的情况下可以调用子类的独特功能)
同类型的对象,执行同一个行为,会表现出不同的行为特征。
父类类型 对象名称 = new 子类构造器;
接口 对象名称 = new 实现类构造器;
- public class Test {
- public static void main(String[] args) {
- // 目标:先认识多态的形式
- // 父类 对象名称 = new 子类构造器();
- Animal a = new Dog();
- a.run(); // 方法调用:编译看左,运行看右
- System.out.println(a.name); // 变量调用调用:编译看左,运行也看左,动物名称
-
- Animal a1 = new Dog();
- a1.run();
- System.out.println(a1.name); // 动物名称
- }
- }
方法调用:编译看左边,运行看右边;
变量调用:编译看左边,运行也看左边。(多态侧重行为多态)
有继承/实现关系:有父类引用指向子类对象:有方法重写。
1.在多态形式下,右边对象可以实现解耦合,便于扩展和维护。
例如:
- Animal a = new Dog();
- a.run();
当new Dog这个对象改变时,后续的业务行为也会随着改对象改变,那么后续的代码无需修改。
2.定义方法的时候,使用父类型作为参数,该方法就可以接收者父类的一切子类对象,体现出多态的扩展性与便利。
多态下会产生一个问题:
多态下不能使用子类独有功能,例如:
- public class Animal {
- public String name = "动物名称";
- public void run(){
- System.out.println("动物可以跑~~");
- }
- }
- public class Dog extends Animal {
- public String name = "狗名称";
- @Override
- public void run() {
- System.out.println("🐕跑的贼溜~~~~~");
- }
-
- /**
- 独有功能
- */
- public void lookDoor(){
- System.out.println("🐕在看🚪!!!");
- }
- }
- public class Tortoise extends Animal {
- public String name = "乌龟名称";
-
- @Override
- public void run() {
- System.out.println("🐢跑的非常慢~~~");
- }
- }
- public class Test {
- public static void main(String[] args) {
- Animal d = new Dog();
- go(d);
- // d.lookDoor();
-
- Animal t = new Tortoise();
- go(t);
- }
-
- /**
- 希望这个方法可以接收一切子类动物对象
- * @param a
- */
- public static void go(Animal a){
- System.out.println("预备~~~");
- a.run();
- System.out.println("结束~~~~");
- }
- }
自动类型转换(从子到父):子类对象赋值给父类的变量指向。
强制类型转换(从父到子):
1.此时必须进行强制类型转换:子类 对象变量 = (子类)父类类型的变量;
2.作用:可以解决多态下的劣势,可以实现调用子类独有的功能;
3.注意:如果转换后的类型和对象真实类型不是同一种类型,那么在转换的时候就会出现ClassCastException。
java建议强转转换前使用instanceof判断当前对象的真实类型,再进行强制转换。
变量名 instanceof 真实类型
判断关键字左边的变量指向的对象的真实类型,是否是右边的类型或者是其子类类型,是则返回true,反之false。
- public class Animal {
- public String name = "动物名称";
- public void run(){
- System.out.println("动物可以跑~~");
- }
- }
- public class Dog extends Animal {
- public String name = "狗名称";
- @Override
- public void run() {
- System.out.println("🐕跑的贼溜~~~~~");
- }
-
- /**
- 独有功能
- */
- public void lookDoor(){
- System.out.println("🐕在看🚪!!!");
- }
- }
- public class Tortoise extends Animal {
- public String name = "乌龟名称";
-
- @Override
- public void run() {
- System.out.println("🐢跑的非常慢~~~");
- }
-
- /**
- 独有功能
- */
- public void layEggs(){
- System.out.println("🐢在下蛋~~~");
- }
- }
- public class Test {
- public static void main(String[] args) {
- // 自动类型转换
- Animal a = new Dog();
- a.run();
- // a.lookDoor(); // 多态下无法调用子类独有功能
-
- // 强制类型转换:可以实现调用子类独有功能的
- Dog d = (Dog) a;
- d.lookDoor();
-
- // 注意:多态下直接强制类型转换,可能出现类型转换异常
- // 规定:有继承或者实现关系的2个类型就可以强制类型转换,运行时可能出现问题。
- // Tortoise t1 = (Tortoise) a;
- // 建议强制转换前,先判断变量指向对象的真实类型,再强制类型转换。
- if(a instanceof Tortoise){
- Tortoise t = (Tortoise) a;
- t.layEggs();
- }else if(a instanceof Dog){
- Dog d1 = (Dog) a;
- d1.lookDoor();
- }
-
- System.out.println("---------------------");
- 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("结束~~~~");
- }
- }
4.多态的案例
需求:
1.使用面向对象编程模拟:设计一个电脑对象,可以安装2个USB设备
2.鼠标:被安装时可以完成接入、调用点击功能、拔出功能。
3.键盘:被安装时可以完成接入、调用打字功能、拔出功能。
分析:
1.定义一个USB的接口(申明USB设备的规范必须是:可以接入和拔出)。
2.提供2个USB实现类代表鼠标和键盘,让其实现USB接口,并分别定义独有功能。
3.创建电脑对象,创建2个USB实现类对象,分别安装到电脑中并触发功能的执行。
- public class Computer {
- /**
- 提供一个安装的入口:行为。
- */
- public void installUSB(USB u){
- u.connect();
-
- // 独有功能
- if(u instanceof Mouse){
- Mouse m = (Mouse) u;
- m.click();
- }else if(u instanceof KeyBoard) {
- KeyBoard k = (KeyBoard) u;
- k.keyDown();
- }
-
- u.unconnect();
- }
- }
- public class KeyBoard implements USB{
- private String name;
-
- public KeyBoard(String name) {
- this.name = name;
- }
-
- @Override
- public void connect() {
- System.out.println(name + "成功的接入了设备了~~~");
- }
-
- @Override
- public void unconnect() {
- System.out.println(name + "成功的从设备弹出了~~~");
- }
-
- /**
- 独有功能
- */
- public void keyDown(){
- System.out.println(name + "写下了:老铁,6666,下次再来哦,老弟~~~~");
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
- }
- public class Mouse implements USB{
- private String name;
-
- public Mouse(String name) {
- this.name = name;
- }
-
- @Override
- public void connect() {
- System.out.println(name + "成功的接入了设备了~~~");
- }
-
- @Override
- public void unconnect() {
- System.out.println(name + "成功的从设备弹出了~~~");
- }
-
- /**
- 独有功能
- */
- public void click(){
- System.out.println(name + "双击点亮小红心~~~~");
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
- }
- public class Test {
- public static void main(String[] args) {
- // a、创建电脑对象
- Computer c = new Computer();
- // b、创建USB设备对象
- USB u = new Mouse("罗技鼠标");
- c.installUSB(u);
-
- USB k = new KeyBoard("双飞燕键盘");
- c.installUSB(k);
- }
-
- }
- public interface USB {
- void connect();
- void unconnect();
- }