个人简介
👀个人主页: 前端杂货铺
⚡开源项目: 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());
}
}
多态调用成员的特点
两句话:
- 调用成员变量的特点:编译看左边,运行也看左边
- 调用成员方法的特点:编译看左边,运行看右边
成员变量:在子类的对象中,会把父类的成员变量也继承下来。
成员方法:如果子类对方法进行了重写,那么在虚方法表中是会把父类的方法进行覆盖的。
接下来,我们进行调用成员变量和成员方法的测试:
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");
}
}
总结
本篇文章,我们学习了多态的相关内容,并认识了多态调用成员的特点及多态的优势与弊端…
好啦,本篇文章到这里就要和大家说再见啦,祝你这篇文章阅读愉快,你下篇文章的阅读愉快留着我下篇文章再祝!
参考资料:
- Java 基础(bilibili-黑马程序员)
- 菜鸟教程–Java