-->

多态

2020-01-19 16:58发布

多态从字面上讲很简单, 就是一个对象, 多种形态. 这个东西有什么用, 我们来看一段代码.

 package com.xyq.bao;

 public class Dog{
     public void eat(){
         System.out.println("狗吃骨头");
     }
 }

 package com.xyq.bao;

 public class Cat{
     public void eat(){
         System.out.println("猫吃鱼");
     }
 }

 package com.xyq.bao;

 public class Person{
     public void feedCat(Cat c){
         c.eat();// 让猫吃
     }

     public void feedDog(Dog d){
         d.eat();// 让狗吃
     }
 }

 package com.xyq.bao;

 public class Test {

     public static void main(String[] args) {

         Person p = new Person();
         Cat c = new Cat();
         Dog d = new Dog();
         p.feedCat(c);
         f.feedDog(d);

     }

 }

大家发现没有. 这个人啊. 好累哦. 喂猫, 喂狗的. 是吧, 但是如果再来一种动物怎么办? 比如养了一只鹦鹉.

 package com.xyq.bao;

 public class Parrot{
     public void eat(){
         System.out.println("鹦鹉吃蔬菜");
     }

 }

这时你发现, 人养不了鹦鹉. 想要养鹦鹉. 必须再添加一个方法. 是吧. 家里养多少动物就得写几个方法. 太麻烦了. 而且. 在喂猫, 喂狗的时候. 内部的代码逻辑基本是一样的. 那能不能简化一下. 可以的. 用多态. 同一个对象, 多种形态, 你想啊. 猫是不是可以当成动物来看, 猫是一种动物, 猫自然而然可以当动物来看啊. 那在java里这个就要写继承了. 对吧.

package com.lewen.opp;

public class Animal {
    public void eat() {
        System.out.println("动物吃东西");
    }
}

package com.lewen.opp;

public class Cat extends Animal {
    public void eat(){
        System.out.println("猫吃鱼");
    }
}

然后. 我们创建猫的时候就可以这样干.

package com.lewen.opp;

public class Client {
    public static void main(String[] args){
        Cat c = new Cat();
        Animal ani = new Cat();
    }
}

把子类的对象赋值给父类的变量. 这个在java里被称为向上转型.

向上转型的优点: 自动转型. 把不相关的东西转化成相同的数据类型. 猫, 狗, 鹦鹉都当成动物来看~~

这样, 作为铲屎官的我就舒服了

统一喂这个动作,而不是来一个动物,去创建一个喂该动物的方法

package com.lewen.opp;

public class Zookeeper {
    public void feed(Animal ani){
        ani.eat();
    }
}

测试:

package com.lewen.opp;

public class Test {
    public static void main(String[] args) {
       Zookeeper p = new Zookeeper();
       Animal c = new Cat();
       Animal d = new Dog();
       p.feed(c);
       p.feed(d);

    }
}

猫吃鱼

狗吃鱼

OK. 没有问题.

我们现在看到的这个就是多态性. 说白了. 不管你把怎么转型. 在执行的时候. JVM会自动去判断这个对象到底是什么的. 这个过程被称为动态数据类型绑定.

多态的现象: 父类的引用执行了子类中的方法

ani.eat(); // ani是父类的引用, eat()运行的时候执行的是子类中的方法.

多态的三个要素:

  1. 要有继承关系
  2. 要重写
  3. 要向上转型

优点: 让程序有超强的可扩展性.

补充一个小知识点:

我们之所以称为向上转型, 是因为在继承体系里. 父类一般画在上面, 子类在下面. 因为按照先后顺序来讲, 肯定是先有父类, 然后才有子类的. 所以把子类的对象赋值给父类的变量. 这个叫向上转型.

那既然有向上转型, 就一定有向下转型.

你把猫转型成了动物. 那站在动物的角度去看猫就必然会屏蔽掉猫自己特有的一些特点. 比如, 抓老鼠. 你可以说猫抓老鼠, 但你不能说动物抓老鼠. 所以. 向上转型之后, 你就不能执行子类中特有的一些方法了. 那如果非要执行怎么办? 把动物再变回猫呗. 但是, 问题来了. 你把猫转成动物是OK的. 安全的. 但是, 你把动物变成猫. 这就有可能会出问题. 万一这个动物不是猫怎么办. 所以java要求. 如果你想把父类的变量转化回子类的类型. 就必须要强转

(转化之后的类型) 变量

package com.lewen.opp;

public class Test {
    public static void main(String[] args) {
        Zookeeper p = new Zookeeper();
        Animal c = new Cat();
        Cat cz = (Cat) c; //强转

        Animal d = new Dog();

        p.feed(c);
        p.feed(d);

    }
}
标签: