多态的应用

一、多态基础语法

 向上转型和向下转型的概念。

        向上转型:子--->父 (upcasting)
            又被称为自动类型转换:Animal a = new Cat();

        向下转型:父--->子 (downcasting)
            又被称为强制类型转换:Cat c = (Cat)a; 需要添加强制类型转换符。
            什么时候需要向下转型?
                需要调用或者执行子类对象中特有的方法。
                必须进行向下转型,才可以调用。
            向下转型有风险吗?
                容易出现ClassCastException(类型转换异常)
            怎么避免这个风险?
                instanceof运算符,可以在程序运行阶段动态的判断某个引用指向的对象
                是否为某一种类型。
                养成好习惯,向下转型之前一定要使用instanceof运算符进行判断。
        
        不管是向上转型还是向下转型,首先他们之间必须有继承关系,这样编译器就不会报错。

instanceof 运算符
避免问题的方法,就是使用 instanceof 的运算符

instanceof 它可以在运行阶段动态判断引用指向的对象的类型

instanceof 的语法(引用 instanceof 类型)

instanceof 的运算结果只能是 true/false

c 是一个引用,c 变量保存了内存地址指向了堆中的对象。
假设(c instanceof Cat)为 true 表示:c 的内存地址指向的是一个 Cat 类型。

假设(c instanceof Cat)为 false 表示:不是一个 Cat 类型的。
 

public class demo1 {
    public static void main(String[] args) {
        Animal c = new Bird();
        if (c instanceof Cat) {//那么就这样做一个判断
            Cat d = (Cat)c;
            d.catchMouse();
        }else {
            System.out.println("转换失败");
        }
    }
}

 

二、什么是多态。
        多种形态,多种状态,编译和运行有两个不同的状态。
        编译期叫做静态绑定。
        运行期叫做动态绑定。
        Animal a = new Cat();
        // 编译的时候编译器发现a的类型是Animal,所以编译器会去Animal类中找move()方法
        // 找到了,绑定,编译通过。但是运行的时候和底层堆内存当中的实际对象有关
        // 真正执行的时候会自动调用“堆内存中真实对象”的相关方法。
        a.move();

        多态的典型代码:父类型的引用指向子类型的对象。(java中允许这样写代码!!!)

三、什么时候必须进行向下转型?
        调用子类对象上特有的方法时。

1、多态在开发中有什么作用?
        降低程序的耦合度,提高程序的扩展力。

        public class Master{
            public void feed(Dog d){}
            public void feed(Cat c){}
        }
        以上的代码中表示:Master和Dog以及Cat的关系很紧密(耦合度高)。导致扩展力很差。

        public class Master{
            public void feed(Pet pet){
                pet.eat();
            }
        }
        以上的代表中表示:Master和Dog以及Cat的关系就脱离了,Master关注的是Pet类。
        这样Master和Dog以及Cat的耦合度就降低了,提高了软件的扩展性。
    
    面向对象的三大特征:
        封装、继承、多态

        真的是一环扣一环。

        有了封装,有了这种整体的概念之后。
        对象和对象之间产生了继承。
        有了继承之后,才有了方法的覆盖和多态。
    
    这里提到了一个软件开发原则:
        七大原则最基本的原则:OCP(对扩展开放,对修改关闭)
        目的是:降低程序耦合度,提高程序扩展力。
        面向抽象编程,不建议面向具体编程。

2、解释之前遗留的问题

    私有方法无法覆盖。

    方法覆盖只是针对于“实例方法”,“静态方法覆盖”没有意义。(这是因为方法覆盖通常和多态联合起来)

    总结两句话:
        私有不能覆盖。
        静态不谈覆盖。

    在方法覆盖中,关于方法的返回值类型。
        什么条件满足之后,会构成方法的覆盖呢?
            1、发生具有继承关系的两个类之间。
            2、父类中的方法和子类重写之后的方法:
                具有相同的方法名、相同的形式参数列表、相同的返回值类型。
        
        学习了多态机制之后:
            “相同的返回值类型”可以修改一下吗?
                对于返回值类型是基本数据类型来说,必须一致。
                对于返回值类型是引用数据类型来说,重写之后返回值类型可以变的更小(但意义不大,实际开发中没人这样写。)。

​​​​​​​​​​​​​继承多态

  • 重载(overload):定义多种同名方法,调用时根据传入参数判定调用哪种方法。
  • 重写(override):子类定义完全相同的方法覆盖父类。

重写是多态的前提,其允许父类引用指向子类对象(引用类型为父类,指向的实际对象类型为子类)。 

Car mycar = new Trunk("Benz");

但不允许子类引用指向父类对象。

Trunk mycar = new Car("Benz");

如果两个类之间存在继承关系,可以进行强制类型转换。强制类型转换只能改变引用类型,实际指向对象类型不会发生变化。

Trunk newCar = (Trunk)mycar;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值