10.多态

多态

多态概述

同一个对象,在不同时刻表现出来的不同形态

如对于猫:

  • 可以说, 猫是猫: 猫 cat = new 猫();
  • 也可以说, 猫是动物: 动物 animal = new 猫();

多态的前提和体现

  • 有继承/实现关系
  • 有方法重写
  • 有父类引用指向之类对象

Animal

package polymorphisms;

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

Cat

package polymorphisms;


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

Demo

package polymorphisms;

public class Demo {
    public static void main(String[] args) {
        Animal a = new Cat();
        a.eat();
    }
}

多态中成员的访问特点

成员变量: 编译看左边, 执行看左边

成员方法: 编译看左边, 执行看右边

因为成员方法有重写,而成员变量没有

Animal

package polymorphisms.member;

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

Cat

package polymorphisms.member;


public class Cat extends Animal {
    public int age = 20;
    public int weight = 10;
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

    public void playGame() {
        System.out.println("猫捉迷藏");
    }
}

Demo

package polymorphisms.member;

public class Demo {
    public static void main(String[] args) {
        // 父类引用指向子类对象
        Animal a = new Cat();
        System.out.println(a.age);  // 编译和执行都是看左侧的类有无
        // System.out.println(a.weight);  // 编译是会看左侧的类中元素, 动物类成员中没有weight

        a.eat();  // 成员方法编译看左侧, 执行看右侧类有无
        // a.playGame();  // 同理,也是看左侧类中有无
    }
}

多态的优点和弊端

好处: 提高了程序的扩展性, 定义方法的时候, 使用父类型作为参数, 将来在使用的时候, 使用具体的子类型参与操作.

弊端: 不能使用子类的特有功能

Animal

package polymorphisms.advantageAndDis;

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

Cat

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

Dog

package polymorphisms.advantageAndDis;

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

    public void lookDoor() {
        System.out.println("狗看门");
    }
}

AnimalOperator

package polymorphisms.advantageAndDis;

public class AnimalOperator {
    /*
    public void useAnimal(Cat c) {
        c.eat();
    }

    public void useAnimal(Dog d) {
        d.eat();
    }
     */
    // 利用多态属性, 方法编译看左边, 方法执行看右侧, 让方法更简洁
    public void useAnimal(Animal a) {
        a.eat();
        // a.lookDoor();  // 多态中无法访问子类特有的方法
    }
}

Demo

package polymorphisms.advantageAndDis;

public class Demo {
    public static void main(String[] args) {
        // 创建动物操作类的对象, 调用方法
        AnimalOperator ao = new AnimalOperator();
        Cat c = new Cat();
        ao.useAnimal(c);

        Dog d = new Dog();
        ao.useAnimal(d);
    }
}

多态中的转型

向上转型:

  • 从子类到父类
  • 父类引用指向子类对象

向下转型

  • 从父类到子类
  • 父类引用转为子类对象

Animal

package polymorphisms.transform;

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

Cat

package polymorphisms.transform;


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

    public void playGame() {
        System.out.println("猫捉迷藏");
    }
}

Demo

package polymorphisms.transform;

public class Demo {
    public static void main(String[] args) {
        // 多态
        Animal a = new Cat();  // 向上转型
        a.eat();
        // a.playGame(); // 报错

        /*
        // 创建cat类对象
        Cat c = new Cat();
        c.eat();
        c.playGame();
         */

        // 向下转型
        Cat c = (Cat)a;
        c.eat();
        c.playGame();
    }
}

多态转型内存问题

Animal

package polymorphisms.transformNotice;

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

Cat

package polymorphisms.transformNotice;


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

    public void playGame() {
        System.out.println("猫捉迷藏");
    }
}

Dog

package polymorphisms.transformNotice;

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

    public void lookDoor() {
        System.out.println("狗看门");
    }
}

Demo

package polymorphisms.transformNotice;

public class Demo {
    public static void main(String[] args) {
        // 多态
        Animal a = new Cat();  // 向上转型
        a.eat();

        // 向下转型
        Cat c = (Cat) a;
        c.eat();
        c.playGame();

        // 向上转型
        a = new Dog();
        a.eat();

        // 向下转型
        // Cat cc = (Cat)a;  // ClassCastException 类型转换异常
        // cc.eat();
        // cc.playGame();
    }
}

原文地址:https://www.cnblogs.com/ryxiong-blog/p/13890201.html