第13讲 面向对象三大特征之多态

1 多态简述

同一个对象,在不同时刻表现出来的不同形态就叫多态

  • 例如:
    • 猫是猫:猫 cat = new 猫()
    • 猫是动物:动物 animal = new 猫()

多态的形式:

  • 具体类多态
  • 抽象类多态
  • 接口多态

2 多态的使用前提

  • 有 继承 / 实现 关系

  • 有方法重写

  • 有父(类 / 接口)引用指向(子 / 实现)类对象👇

    //父类引用  指向  子类对象
    父类 对象名 = new 子类名();
    
    //父接口引用  指向  实现类对象
    接口名 对象名 = new 实现类名(); 
    

3 多态中成员访问特点

public class Animal() {
    public int height = 10;
    
    public void eat() {
        Sout: "动物吃东西";
    }
}

class Cat extends Animal() {
    public int height = 20;
    public int weight = 40;
    
    @Override
    public void eat() {
        Sout: "猫吃鱼";
    }
    
    public void play() {
        Sout: "猫玩老鼠";
    }
}

3.1 成员变量

编译看左边,运行看左边 (因为成员变量没有重写)

  1. 编译看左边: javac在编译代码的时候,会看左边(父类)有没有这个成员变量
  2. 运行看左边: java在运行代码的时候,会拿左边(父类)的成员变量的值作为最终值
public class Demo() {
    public static void main(String[] args) {
        Animal ani = new Cat();
    
        Sout: ani.height;// 输出:10  (来自父类)
        
    	Sout: ani.weight;// 报错,因为Animal类里没有成员变量weight
    }
}

3.2 成员方法

编译看左边,运行看右边 (因为成员方法有重写)

  1. 编译看左边: javac在编译代码的时候,会看左边(父类)有没有这个成员方法
  2. 运行看右边: java在运行代码的时候,会拿右边(子类)的成员方法作为最终值
public class Demo() {
    public static void main(String[] args) {
    	Animal ani = new Cat();
        
    	ani.age();// 输出:猫吃鱼 (来自子类)
    	
    	ani.play();//报错,因为Animal类没有成员方法play()
    }
}

4 多态的利与弊

好处

  • 定义方法时,使用父类型作为参数,可以接收所有的子类对象。以后再使用的时候,只需要使用具体的子类型参与操作即可。提高了程序的扩展性

  • 在多态形式下,右边对象可以实现解耦合,便于扩展和维护。

    ​ 如 A extends C, B extends C。C类中有一个工作:打扫卫生。

    ​ 起初A类对象在打扫卫生:C c = new A(); c.work();

    ​ 现在想让B类对象去打扫卫生,只需要改变子类对象C c = new B();,后续所有的代码都不需要更改。

弊端

  • 不能使用子类的特有功能(解决方法见下:多态的转型)
public class Demo() {
    public static void main(String[] args) {
    	Animal ani = new Cat();
        
    	ani.age();// 输出:猫吃鱼 (来自子类)
    	
    	ani.play();//报错,因为Animal类没有成员方法play()
    }
}

class Animal() {
    public int height = 10;
    
    public void eat() {
        Sout: "动物吃东西";
    }
}

class Cat extends Animal() {
    public int height = 20;
    public int weight = 40;
    
    @Override
    public void eat() {
        Sout: "猫吃鱼";
    }
    
    public void play() {
        Sout: "猫玩老鼠";
    }
}

5 多态的转型

5.1 向上转型(自动类型转换)

从子到父

  • 父类引用指向子类对象
//向上转型
Animal ani = new Cat();	

5.2 向下转型(强制类型转换)

从父到子

  • 父类引用转为子类对象

作用: 可以转为真正的子类类型,从而调用子类独有的功能

转换类型与真实对象类型不一致的时候会报错,所以:

转型需谨慎,要加以判断:

语法:a instanceof B //变量a是不是B类型,如果是,返回true

public class Demo() {
    public static void main(String[] args) {
    	Animal ani = new Cat();
        
        //ani是不是猫类型?是就转型,不是就不转
        if(ani instanceof Cat) { 
            //向下转型
            Cat cat = (Cat)ani;
            
            //此时就可以用子类的特有功能
            cat.play();
        } else {
            System.out.println("没有该类型,无法转换");
        }
    }
}

关于强转前的判断,jdk14以后有新特性:

语法:a instanceof B b

​ //变量a是不是B类型,如果是,则强转为B类型,转换后的变量名更改为b;如果不是不强转,结果为false

if(ani instanceof Cat cat) { 
	cat.play();
} else {
	System.out.println("没有该类型,无法转换");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值