面向对象——多态详解

人生之路不会是一帆风顺的,我们会遇上顺境,也会遇上逆境,在所有成功路上折磨你的,背后都隐藏着激励你奋发向上的动机,人生没有如果,只有后果与结果,成熟,就是用微笑来面对一切小事。

导读:本篇文章讲解 面向对象——多态详解,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文


活动地址:CSDN21天学习挑战赛

面向对象——多态详解

前面我们对面向对象的三大特征:封装、继承、多态进行了简单的梳理,今天我们对多态进行一个更深入的学习。

什么是多态?

多态(Polymorphism)属于面向对象的三大特征之一,它的前提是封装形成独立体,独立体之间存在继承关系,从而形成多态机制。多态是同一个行为具有多个不同表现形式的能力。多态就是“同一个行为”发生在“不同对象上”会产生不同的效果。

多种形态,多种状态,编译和运行有两个不同的状态

  • 编译期叫做静态绑定
  • 运行期叫做动态绑定

方法重载与方法覆盖(重写)的区别

方法重载发生在同一个一个类中

方法覆盖 是发生在具有继承关系的父子类之间

方法重载是在一个类中,方法名相同,参数列表不同

方法覆盖是具有继承关系的父子类,并且重写之后的方法必须和之前的方法一致:方法名一致、参数列表一致、返回值类型一致。

多态的基础语法

向上转型和向下转型

在Java中允许两种这样的语法出现,一种是向上转型(Upcasting),一种是向下转型(Downcasting),向上转型是指子类型转换为父类型,可理解为自动类型转换,向下转型是指父类型转换为子类型,又可以理解为强制类型转换。调用子类特有方法时必须进行向下转型。

注意:无论是向上转型还是向下转型,两种类型之间必须是继承关系,没有继承关系编译器会报错!!!

示例程序:

package com.shouyerenst.OOP;

public class Animal {
    public void move(){
        System.out.println("动物在移动!!!");
    }
}
class Cat extends Animal{
     //对move方法重写
    public void move(){
            System.out.println("猫在走猫步!!!");
        }
     //Cat类特有的方法
     public void catchMouse(){
         System.out.println("猫正在抓老鼠!!!");
     }
}
class Bird extends Animal{
    //对move方法重写
    public void move(){
        System.out.println("鸟儿在飞翔!!!");
    }
    public void sing(){//Bird特有的方法
        System.out.println("鸟儿在歌唱!!!");
    }
}

测试程序:

package com.shouyerenst.OOP;

public class AnimalTest {
    public static void main(String[] args) {
        Animal a1 = new Animal();
        a1.move();
        
        Cat c1 = new Cat();
        c1.move();
        
        Bird b1 = new Bird();
        b1.move();
        System.out.println("--------------------------");
        //父类型引用允许指向子类型引用
        //向上转型
        Animal a2 = new Cat();
        a2.move();
        Animal a3 = new Bird();
        a3.move();
        //向下类型转换
        //这里编译器认为a4是一个Animal类型,如果要使用Cat(Animal的子类)中特有的方法,就必须向下转型了
        Animal a4 = new Cat();
        Cat x = (Cat) a4;
        x.catchMouse();
        
        /*
        下面代码在编译的时候是没有任何问题的,但是运行时会出现java.lang.ClassCastException(类型转换异常)
        Animal a5 = new Bird();
        Cat y = (Cat) a5;
        y.catchMouse();
        */
    }
}

AnimalTest中注释代码错误分析

编译阶段:(静态绑定)

编译器认为a5是一个Animal类型,而Animal和Cat具有继承关系,所以可以向下转型为Cat对象,调用Cat类独有方法,可以编译通过

运行阶段:(动态绑定)

在堆内存中创建对象的时候实际上创建的是Bird类型对象,而Bird类与Cat类并不具有继承关系,所以无法完成向下转型,也无法调用Cat类的独有方法。这里出现的异常叫做java.lang.ClassCastException(类型转换异常),这是一个同空指针异常同样重要的异常类型,我们需要注意。

如何避免ClassCastException

instanceof运算符

有时候需要在运行时判断一个对象是否属于某个引用类型,这时可以使用instanceof运算符,instanceof运算符语法格式如下:

obj instanceof type

其中obj是一个对象,type是引用类型,如果obj对象是type引用类型实例则返回true,否则false。

测试程序中的注释代码就可以改成如下格式:

 Animal a5 = new Bird();
        if(a5 instanceof Cat){
            Cat y = (Cat) a5;
            y.catchMouse();
        } else if (a5 instanceof Bird) {
            Bird y = (Bird) a5;
            y.sing();
        }

任何时间,任何地点,在进行向下转型(强制类型转换)的时候我们需要使用instanceof运算符进行判断,避免出现类型转换异常,这是Java中规范要求的。

多态在开发中的作用

多态在开发中的作用是降低程序的耦合度,提高程序的扩展力。

举个栗子!!!

public class Master{
    public void feed(Dog d){}
    public void feed(Cat c){}
}

//以上代码中表示:Master和Dog以及Cat的关系很紧密(耦合度搞),导致其扩展力很差。

public class Master{
    public void feed(Pet pet){}
}
//以上代码表示:Master和Dog以及Cat的关系就脱离了,Master关注的是Pet类,降低了Master和Dog以及Cat类的耦合性,提高了软件的扩展性。

总结

现在我们再来回顾面向对象的三大特征:封装、基础、多态

他们之间的关系是一环扣一环

首先得封装成一个整体才有了继承的概念

有了继承关系才有了多态的实现 —>Animal a1 = new Cat();

在这里插入图片描述


感觉不错的话,动手点个赞吧!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/125491.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!