个人简介

个人主页: 前端杂货铺
开源项目: rich-vue3 (基于 Vue3 + TS + Pinia + Element Plus + Spring全家桶 + MySQL)
‍️学习方向: 主攻前端方向,正逐渐往全干发展
个人状态: 研发工程师,现效力于中国工业软件事业
人生格言: 积跬步至千里,积小流成江海
推荐学习:开源 rich-vue3 前端面试宝典 Vue2 Vue3 Vue2/3项目实战 Node.js实战 Three.js

个人推广:每篇文章最下方都有加入方式,旨在交流学习&资源分享,快加入进来吧

内容参考链接
Java基础(一)Hello World,8种数据类型,键盘录入
Java基础(二)数组,方法,方法重载
Java基础(三)类和对象、构造方法
Java基础(四)字符串、StringBuffer、StringBuilder、StringJoiner
Java基础(五)ArrayList
Java基础(六)继承

前言

大家好,这里是前端杂货铺。

本篇文章,我们学习多态、多态调用成员的特点以及认识其优势与弊端。


多态

多态:同类型的对象,表现出的形态不同。

多态的表现形式:父类类型 对象名称 = 子类对象。Fu f = new Zi()

多态的前提:有继承关系、有父类引用指向子类对象、有方法重写。

多态的好处:使用父类型作为参数,可以接收所有子类对象,体现多态的扩展性与便利。

假如我们现在有一个教务系统,存在管理员、老师、学生三种身份,我们通过类来打印他们各自的信息,我们要怎么设计呢?

Test.java

package com.javabasic.polymorphism;

public class Test {
    public static void main(String[] args) {
        // 创建三个对象,并调用register方法
        Student student = new Student();
        student.setName("前端杂货铺");
        student.setAge(20);

        Teacher teacher = new Teacher();
        teacher.setName("张三");
        teacher.setAge(30);

        Admin admin = new Admin();
        admin.setName("管理员");
        admin.setAge(25);

        register(student);
        register(teacher);
        register(admin);
    }

    // 此方法既能接收老师,又能接收学生,还能接收管理员
    // 只能把参数写成这三个类型的父类
    public static void register(Person p) {
        p.show();
    }
}

Person 父类,用于显示子类对象实例的信息。

Person.java

package com.javabasic.polymorphism;

public class Admin extends Person {
    @Override
    public void show() {
        System.out.println("管理员的信息:" + getName() + ", " + getAge());
    }
}

Person 的子类 Admin,打印管理员的信息。

Admin.java

package com.javabasic.polymorphism;

public class Admin extends Person {
    @Override
    public void show() {
        System.out.println("管理员的信息:" + getName() + ", " + getAge());
    }
}

Person 的子类 Teacher,打印老师的信息。

Teacher.java

package com.javabasic.polymorphism;

public class Teacher extends Person {
    @Override
    public void show() {
        System.out.println("老师的信息:" + getName() + ", " + getAge());
    }
}

Person 的子类 Student,打印学生的信息。

Student.java

package com.javabasic.polymorphism;

public class Student extends Person {
    @Override
    public void show() {
        System.out.println("学生的信息:" + getName() + ", " + getAge());
    }
}

在这里插入图片描述


多态调用成员的特点

两句话:

  1. 调用成员变量的特点:编译看左边,运行也看左边
  2. 调用成员方法的特点:编译看左边,运行看右边

成员变量:在子类的对象中,会把父类的成员变量也继承下来。
成员方法:如果子类对方法进行了重写,那么在虚方法表中是会把父类的方法进行覆盖的。

接下来,我们进行调用成员变量和成员方法的测试:

package com.javabasic.demo;

public class Test {
    public static void main(String[] args) {
        Animal animal = new Dog();

        // 调用成员变量:编译看左边,运行也看左边
        // 编译看左边:javac 编译代码时,会看左边的父类中有没有这个变量,如果有,编译成功,如果没有编译失败
        // 运行也看左边:java 运行代码时,实际获取的就是左边父类中成员变量的值
        System.out.println(animal.name); // animal

        // 调用成员方法:编译看左边,运行看右边
        // 编译看左边:javac编译代码时,会看左边的父类中有没有这个方法,如果有,编译成功,如果没有编译失败
        // 运行看右边:java运行代码时,实际上运行的是子类中的方法
        animal.show(); // dog --- show方法
    }
}

class Animal {
    String name = "animal";

    public void show() {
        System.out.println("Animal --- show方法");
    }
}

class Dog extends Animal {
    String name = "dog";

    @Override
    public void show() {
        System.out.println("dog --- show方法");
    }
}

class Cat extends Animal {
    String name = "cat";

    @Override
    public void show() {
        System.out.println("cat --- show方法");
    }
}

在这里插入图片描述


多态的优势与弊端

优势:方法中,使用父类型作为参数,可以接受所有子类对象。

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

如果我们就是要调用子类中特有的功能该如何是好呢?—— 类型转换

package com.javabasic.demo;

public class Test {
    public static void main(String[] args) {
        Animal animal = new Dog();

        // 会报错,因为 animal 中不存在 eat()
        // animal.eat();


        // 解决方案:进行类型转换
        if (animal instanceof Dog dog) {
            dog.eat();
        } else if (animal instanceof Cat cat) {
            cat.sleep();
        } else {
            System.out.println("没有这个类型,无法转换");
        }
    }
}

class Animal {
    String name = "animal";

    public void show() {
        System.out.println("Animal --- show方法");
    }
}

class Dog extends Animal {
    String name = "dog";

    @Override
    public void show() {
        System.out.println("dog --- show方法");
    }

    public void eat() {
        System.out.println("dog --- 啃骨头");
    }
}

class Cat extends Animal {
    String name = "cat";

    @Override
    public void show() {
        System.out.println("cat --- show方法");
    }

    public void sleep() {
        System.out.println("cat --- sleep");
    }
}

在这里插入图片描述


总结

本篇文章,我们学习了多态的相关内容,并认识了多态调用成员的特点及多态的优势与弊端…

好啦,本篇文章到这里就要和大家说再见啦,祝你这篇文章阅读愉快,你下篇文章的阅读愉快留着我下篇文章再祝!


参考资料:

  1. Java 基础(bilibili-黑马程序员)
  2. 菜鸟教程–Java

在这里插入图片描述


点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部