java基础-多态

多态

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

  • 举例
    我们可以说猫是猫: 猫 cat = new 猫();
    我们也可以说猫是动物: 动物 animal = new 猫();
    这里猫在不同的时刻表现出来了不同的形态,这就是多态
  • 多态的前提和体现
  1. 有继承/实现关系
  2. 有方法重写
  3. 有父类引用指向子类对象
public class Animal {
    public void eat() {
        System.out.println("动物吃东西");
    }
}
public class Cat extends Animal { // 继承
    @Override // 重写方法
    public void eat() {
        System.out.println("猫吃东西");
    }
}
    public static void main(String[] args) {
        // 父类引用指向子类对象
        Animal a = new Cat();
    }

多态中成员访问特点

  • 成员变量: 编译看左边,执行看左边
  • 成员方法: 编译看左边,执行看右边
    为什么成员变量和成员方法的访问不一样呢?
  • 因为成员方法有重写,而成员变量没有
public class Animal {

    public int age = 40;

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

    public int age = 30;
    public int weight = 10;

    @Override
    public void eat() {
        System.out.println("猫吃东西");
    }

    public void playGame() {
        System.out.println("猫玩游戏");
    }
}
    public static void main(String[] args) {
        // 由父类引用指向子类对象
        Animal a = new Cat();

        System.out.println(a.age);
        // System.out.println(a.weight); // 编译需要看左边的Animal,看父类中有无

        a.eat(); // 猫吃鱼 运行看右边,看子类中有无
        // a.playGame(); // 编译需要看左边的Animal,看父类中有无
    }

多态的好处和弊端

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

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

public class Animal {

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

    /*public void useAnimal(Cat c) { // Cat c = new Cat();
        c.eat();
    }
    public void useAnimal(Dog d) { // Dog d = new Dog();
        d.eat();
    }*/

    public void useAnimal(Animal a) {
        // Animal a = new Cat(); 编译看左边,执行看右边
        a.eat();
    }
}
public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}
public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("狗吃屎");
    }
}
    public static void main(String[] args) {
        // 创建动物操作类的对象,调用方法
        AnimalOperator ao = new AnimalOperator();
        Cat c = new Cat();
        ao.useAnimal(c); // 猫吃鱼

        Dog d = new Dog();
        ao.useAnimal(d); // 狗吃屎
    }

多态中的转型

  • 向上转型: 从子到父,父类引用指向子类对象
  • 向下转型: 从父到子,父类引用转为子类对象
public class Animal {

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

    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
    public void playGame() {
        System.out.println("猫玩游戏");
    }
}
    public static void main(String[] args) {
        // 多态
        Animal a = new Cat(); // 向上转型
        a.eat();
        // a.playGame(); // 编译看左边,因为父类中没有playGame(),所以不能通过编译

        // 那就是想用呢?

        /*// 方法1: 创建Cat类的对象
        Cat c = new Cat();
        c.eat();
        c.playGame(); // 但是,猫对象,当然可以用猫的方法*/

        // 方法2: 向下转型
        Cat c = (Cat)a; // 类似强制类型转换
        c.eat();
        c.playGame();
    }

多态转型内存图解

多态转型内存图解.png
多态转型内存图解2.png
多态转型内存图解3.png
多态转型内存图解4.png
多态转型内存图解5.png
多态转型内存图解6.png
多态转型内存图解7.png
多态转型内存图解8.png

案例: 猫和狗

public class Animal {

    private String name;
    private int age;

    public Animal() {
    }

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

    public Cat() {
    }

    public Cat(String name, int age) {
        super(name, age);
    }

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

    public Dog() {
    }

    public Dog(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println("狗吃屎");
    }
}
    public static void main(String[] args) {
        Animal a = new Cat();
        a.setName("黑猫");
        a.setAge(5);
        System.out.println(a.getName() + "," + a.getAge() + "岁");
        a.eat();

        Animal a2 = new Cat("白猫",6);
        System.out.println(a2.getName() + "," + a2.getAge() + "岁" );
        a2.eat();
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容