Java基础 | 多态

java面向对象三大特征:封装、继承、多态。

多态(Polymorphism)按字面的意思就是“多种状态”。在面向对象语言中,接口的多种不同的实现方式即为多态。

多态的转型:
向上转型 & 向下转型

​ 前提是要有继承关系!!!!!。

向上转型(upcasting):子转父。 父类 x = new 子类();
向下转型(downcasting):父转子。 子类 x = new 父类();

先上代码,

//Animal父类
public class Animal_01 {
    public void move(){
        System.out.println("动物在移动");
    }
}
//Animal的子类,猫类
public class Cat_Animal extends Animal_01{
    //对move重写
    public void move(){
        System.out.println("猫在喵喵喵");
    }
    // catchMouse 方法是 Cat_Animal类特有的方法
    public void catchMouse(){      
        System.out.println("猫正在抓老鼠。");
    }
}
//test类
public class D001 {
    public static void main(String[] args) {
        Animal_01 a1 = new Animal_01();
        a1.move();  //输出:动物在移动

        Cat_Animal a2 = new Cat_Animal();
        a2.move();  //输出:猫在喵喵喵

       Animal_01 q3 = new Cat_Animal();
        q3.catchMouse();
        //编译不通过,因为编译器只知道q3的类型是Animanl,去Animal.class 找catchMouse()方法,
        //结果没找到,所以静态绑定失败,编译报错,无法运行。

分析:
java程序分为编译阶段和运行阶段。

编译阶段:
​ 对于编译器来说,编译器只知道q1 的类型的Animal,
​ 所以编译器在检查语法的时候,会去 Animal.class字节码文件中查找move()方法, 找到了,绑定上move()方法,编译通过,静态绑定成功。(编译阶段属于静态绑定)。

运行阶段:
​ 运行阶段的时候,实际上在堆内存当中创建的java对象是Cat对象,所以move的时候真正参与的是Cat,所以运行阶段会动态执行cat对象的move方法,这个过程属于运行阶段绑定。(运行阶段绑定属于动态绑定)。

多态的多种形态:
​ 编译的时候一种形态,
​ 运行的时候一种形态。

多态指的是(向上):
​ 父类引用指向子类对象。
​ 包括编译阶段和运行阶段。
​ 编译阶段:绑定父类的方法。
​ 运行阶段:动态绑定子类对象的方法。

由此也可以看出什么是多态:
多种形态,多种状态,运行和编译有着不同的状态。
编译期叫动态绑定,运行期叫静态绑定。

向下转型:

​ (强制转换)
什么时候使用向下转型?
​ 当访问的是子类对象中 “特有” 的方法时,此时必须使用向下转型,才可以调用。

//在test文件
//向下转型。
Animal_01 w1 = new Cat_Animal();
Cat_Animal w2 =(Cat_Animal)w1;
w2.catchMouse();  //输出:猫正在抓老鼠

向下转型有没有风险?

​ 有。 类型转换异常

​ java.lang.ClassCastException:

下面程序错误示范:

//在test文件
Animal_01 a6 = new Bird_Animal();  //表面上是 animanl_01 ,其实是 Bird_Animal 。
Cat_Animal y = (Cat_Animal)a6;
y.catchMouse();   //报错, java.lang.ClassCastException:

​ 编译阶段:编译器监测到a6这个引用还是Animal_01 类型,而Animal_01 与 Cat_Animal 之间存在继承关系,所以可以向下转型。 编译没问题。
​ 运行阶段: 堆内存实际创建的是Bird对象,,在实际运行过程中,你用Bird对象转换成Cat对象,是不行的,因为Bird 和 cat 之间没有继承关系。

​ 异常:(和空指针异常一样重要,也很经典)
​ java.lang.ClassCastException:
​ class Duotai.Bird_Animal cannot be cast to class Duotai.Cat_Animal
​ (Duotai.Bird_Animal and Duotai.Cat_Animal are in unnamed module of loader ‘app’)
​ 类型转换异常。

怎么解决类型转换异常?

运算符: instanceof

  1. 在运行阶段 动态判断 引用指向的对象的类型。
  2. instanceof 的语法是:  (引用    instanceof    类型)。
  3. instanceof 运算符的运算结果只能是 true & false。
  4. c是一个引用,是一个对象,c变量保存了内存地址指向堆中的对象,
     假设 (c instanceof cat) 为true:c引用指向了堆内存中的java对象 是 一个cat。
     假设 (c instanceof cat) 为false:c引用指向了堆内存中的java对象 不是 一个cat。
//怎么避免异常发生?
//向下转型  时都要使用 instanceof 运算符判断。
if (a6 instanceof Cat_Animal) {  //如果a6是cat,再进行强制类型转换。
    Cat_Animal y = (Cat_Animal) a6;
    y.catchMouse();
}

所以,要养成习惯,向下转型之前一定要用 instanceof 运算符进行判断。

我为什么要用instanceof?

Animal_01 q1 = new Bird_Animal();  //虽然你可以看出来是对象是鸟,但还是要用instanceof。
Animal_01 q2 = new Cat_Animal();  //原因:你以后可能肉眼看不到。  比如 方法不是你自己写的。我不知道传过来一个什么变量。
                                  //所以我加个判断,要向下转型,我要确定XXX。

多态的作用

  1. 多态在开发中的作用?

    降低程序耦合度,提高程序的扩展力。

    软件拓展过程,修改代码越少越好,修改的代码繁多,稳定性差,未知的风险大。

    什么是扩展性?

    比如电脑内存条坏了,买条新的换上就好了,就说明电脑扩展性好。

    软件开发七大原则: OCP(开闭原则)

    对扩展开发,对修改关闭。

    在软件的扩展过程中,代码修改的越少越好。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值