多态

作者: 若兮缘 | 来源:发表于2018-12-02 20:32 被阅读11次

理解多态

多态,即多种形态,面向对象程序设计语言当中最核心的特征,理解多态能帮助我们更好的进行程序设计。

生活中的多态

我们知道动物一般都有吃东西、跑、跳、叫等等一些通用的行为能力,但是不同动物针对这些行为的表现形式是不同的,比如猫、狗、兔子喜欢吃的东西各有不同,它们的叫声也不一样。

再比如当我们按下键盘中的F1键时,针对当前工作窗口的不同它也将会显示不同的帮助文档,比如在eclipse中弹出的是关于eclipse中的帮助文档,在word中就弹出word的帮助文档。

所以可以看出同样一种行为,在不同的对象上会产生不同的显示结果,这就是生活中的多态。

程序中的多态

在程序设计中,多态就意味着允许不同类的对象对同一消息做出不同的响应。广泛意义上而言,多态可以分为:编译时多态和运行时多态。
编译时多态(设计时多态):表现形式为方法重载。
运行时多态:JAVA运行时系统根据调用该方法的实例的类型来决定选择调用哪个方法。我们平时所说的多态大多指的是运行时多态。

多态存在的必要条件
  1. 满足继承关系
  2. 重写方法
  3. 父类引用指向子类对象

多态实现

定义子父类

定义动物父类及猫、狗子类,类的关系图

父类的定义:

/**
 * 动物类
 */
public class Animal {
    //属性:昵称、年龄(省略getter和setter)
    private String name;
    private int month;
    //构造方法
    public Animal(){
        
    }
    public Animal(String name,int month){
        this.name=name;
        this.month=month;
    }
    
    //方法:吃东西
    public void eat(){
        System.out.println("动物都有吃东西的能力");
    }
}

子类的定义:

/**
 * 猫
 */
public class Cat extends Animal{
    //属性:体重
    private double weight;
    //构造方法
    public Cat(){
        
    }
    public Cat(String name,int month,double weight){
        super(name,month);
        this.weight=weight;
    }
    
    //方法:跑动
    public void run(){
        System.out.println("小猫快乐的奔跑");
    }
    //方法:吃东西(重写父类方法)
    @Override
    public void eat() {
        System.out.println("猫吃鱼~~");
    }
}
/**
 * 狗
 */
public class Dog extends Animal {
    //属性:性别
    private String sex;
    //构造方法
    public Dog(){
        
    }
    public Dog(String name,int month,String sex){
        this.setMonth(month);
        this.setName(name);
        this.setSex(sex);
    }
    
    //方法:睡觉
    public void sleep(){
        System.out.println("小狗有午睡的习惯");
    }
    //方法:吃东西(重写父类方法)
    @Override
    public void eat() {
        System.out.println("狗吃肉~~");    
    }
}
向上转型(Upcase)
  • 向上转型又叫自动转型、隐式转型。向上转型就是父类引用指向子类实例,是小类型到大类型的转换。
  • 向上转型是安全的,因为任何子类都继承并接受了父类的方法。
  • 向上转型后可以调用子类重写父类的方法以及父类派生的方法,无法调用子类独有的方法。
  • 父类中的静态方法无法被子类重写,所以向上转型之后,只能调用到父类原有的静态方法。
    public static void main(String[] args) {
        //多态的表现:都使用同一父类对象类型完成同一种行为,表现形式却各不相同
        Animal one = new Animal();
        Animal two = new Cat();
        Animal three = new Dog();
        one.eat(); //动物都有吃东西的能力
        two.eat(); //猫吃鱼~~
        three.eat(); //狗吃肉~~
    }
动态绑定

多态的实现可以通过向上转型和动态绑定机制来完成,向上转型实现了将子类对象向上转型为父类类型,而动态绑定机制能识别出对象转型前的类型,从而自动调用该类的方法,两者相辅相成。
绑定:绑定就是将一个方法调用同一个方法所在的类连接到一起就是绑定。绑定分为静态绑定和动态绑定两种。
静态绑定:在程序运行之前进行绑定(由编译器和链接程序完成的),也叫做前期绑定。
动态绑定:在程序运行期间由JVM根据对象的类型自动的判断应该调用哪个方法,也叫做后期绑定。

静态绑定的例子
如有一类Human,它派生出来三个子类Chinese类、American类和British类,三个子类中都重写了父类中的方法speak(),在测试类中用静态绑定的方式调用方法speak()。

这种调用方式是在代码里指定的,编译时编译器就知道谁调用的是Chinese的speak(),谁调用的是American的speak()。

动态绑定的例子

此时, Human类中随机生成Chinese类、American 类和British 类的对象,编译器不能根据代码直接确定调用哪个类中的speak()方法,直到运行时才能根据产生的随机数n的值来确定human[i]到底代表哪一个子类的对象,这样才能最终确定调用的是哪个类中的speak()方法,这就是动态绑定。

向下转型(Downcast)

向下转型是与向上转型相对的概念,它是用子类引用指向父类实例,必须进行强转,所以向下转型又叫做强制类型转换。
向下转型后就可以调用子类特有的方法了,但是必须满足转型条件才能进行强转。

    public static void main(String[] args) {
        Animal one = new Animal();
        Animal two = new Cat();
        Animal three = new Dog();
        //向下转型
        Cat temp = (Cat)two;
        temp.eat();
        temp.run();
        //类型不匹配无法进行转换,运行时出现异常:ClassCastException
        //如何避免出现该异常?使用instanceof运算符
        Cat temp2 = (Cat)one;
        Dog temp3 = (Dog)two;
    }
instanceof运算符
  • 用来判断对象是否满足某个特定类型实例特征,满足则返回true,一般用于if语句中。
  • 实际开发中通常判断某个对象是否是某个类或者其子类的实例,或者是某个接口的实现。
  • 通过instanceof运算符可以保证向下转型的安全性,避免出现类型转换的异常,提高代码的健壮性。

类型转换案例

案例1:实现喂宠物的功能,要求如下
喂猫咪:吃完东西后(eat方法),主人会带着去玩线球(playBall方法)
喂狗狗:吃完东西后(eat方法),主人会带着狗狗去睡觉(sleep方法)
实现方案:
在喂养动物的种类比较少时,两种方案均可,但是当我们需要实现更多动物的喂养需求时方案1需要增加非常多的方法,而方案2则只需要修改方法体的内部实现,增加相应动物子类的处理方法即可。

案例2:根据条件决定饲养何种宠物
空闲时间多:养狗狗;空闲时间不多:养猫咪
实现方案

结论:在实际的开发当中,如果需要同一个操作行为针对不同条件(参数)返回不同的实例对象,或者完成不同的操作结果时,就可以使用这种多态的方式实现,类型转换的优势就可以充分体现出来了。

多态总结

  • 多态是同一个行为具有多个不同表现形式或形态的能力,意味着允许不同类的对象对同一消息做出不同的响应
  • 多态的表现形式(实现方式)为方法重载、方法重写、接口实现
  • 多态作用是消除类型之间的耦合关系,提高程序的灵活性和可扩展性

相关文章

  • 1.9 多态基本概念

    本小节知识点: 【了解】什么是多态? 【掌握】多态的条件 【了解】多态的优点 1.什么是多态? 什么是多态:多态就...

  • C++ 的多态(Polymorphism), virtual f

    多态 c++支持两种多态,编译时多态和运行时多态但其实编译时多态根本不是真正的多态,编译时多态就是函数的重载,ov...

  • 详解Java多态

    详解Java多态 多态定义 多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化多态性和包含多态性。多态...

  • 多态

    1.多态 1.多态 1.1 要点 多态是方法的多态,不是属性的多态 多态的存在有三个必要条件:继承;方法重写;父类...

  • java多态面试题

    java多态性 多态分两种: (1) 编译时多态(设计时多态):方法重载。 (2) 运行时多态:JAVA运...

  • Java_basic_10: 多态polymorphism

    多态polymorphism 多态是指对象的多种形态 主要可以分为引用多态和方法多态 继承是多态的实现基础 引用多...

  • 六、多态与虚函数

    多态的基本概念 多态 多态分为编译时多态和运行时多态。 编译时多态主要是指函数的重载(包括运算符的重载)。对重载函...

  • Java基础之面向对象

    1.多态,继承,封装 Java实现多态有哪些必要条件?具体怎么实现?多态的实现原理?多态的作用? 答:多态的优点 ...

  • java多态面试题

    java多态性 多态分两种: (1) 编译时多态(设计时多态):方法重载。 (2) 运行时多态:JAVA运行时...

  • 多态与虚函数

    多态的基本概念 实现了多态机制的程序,可以使用同一个名字完成不同的功能。 多态分为编译时多态和运行时多态。 多态 ...

网友评论

    本文标题:多态

    本文链接:https://www.haomeiwen.com/subject/tfrscqtx.html