Java 的三大特性是我们在刚接触 Java 的时候就一直在叨叨,那到底什么是 封装、继承
、多态呢?封装和继承相对来说好理解一些,这篇文章主要来说一下 多态。
文章目录
- 1、多态娱乐初始版:
- 2、多态娱乐改进版:
1、多态娱乐初始版:
在介绍多态之前先来看一下之前不用多态多出现的问题,通过代码来详细看一下(不要慌,代码很好懂):
代码搞起来:
Application.java
package com.pxl.form.versionOne;
import com.pxl.form.versionOne.ExperimentCourse;
import com.pxl.form.versionOne.Teacher;
public class Application {
public static void main(String[] args) {
Teacher teacher = new Teacher();
ExperimentCourse course = new ExperimentCourse();
teacher.Set(course);
System.out.println("今天上什么课?");
teacher.Answer();
}
}
Teacher.java
package com.pxl.form.versionOne;
public class Teacher {
private ExperimentCourse course;
public void Set(ExperimentCourse course) {
this.course = course;
}
public void Answer() {
System.out.println(course);
}
}
ExperimentCourse.java
package com.pxl.form.versionOne;
public class ExperimentCourse {
public String toString()
{
return "今天上实验课。";
}
}
问题错误:
经过在 idea 编译器环境下执行 多态娱乐初始版 ,由于当前包下只有一个 ExperimentCourse 类,所以在 Application 类中进行调用方法的时候并不会出现什么问题,但是,当出现多个相关课程类的时候,例如 DataBaseCourse 的时候,我们就会发现其中的问题:
package com.pxl.form;
import com.pxl.form.versionTwo.Course;
/**
* 实现 Course 接口,重写 toString 方法
*/
public class DataBaseCourse {
public String toString(){
String str = "上数据库课!";
return str;
}
}
2、多态娱乐改进版:
分析上面出现的问题,追根溯源,我们发现在Teacher类中依赖注入(调用Set方法)的时候属性只有ExperimentCourse 类的属性,所以当我们再调用set 方法的时候,必然是会报错的,可以发现,现在明确出现的问题就是一个 Teacher 类只能有一门课程,显然在实践生活中也是很少见的,那如何解决这个问题呢?
我们发现,在 每门课程 都有相同的一些特征,“上xxx课”,这是我们是否可以让 Teacher 类中的属性成为一个 Course 类,这样每门课都去实现 Course 接口,在调用 Answer() 方法的时候就会去重写 传入的类 的 toString () 方法。
通过上面的解决办法我们就会发现,当有一门新的课程的时候,我们不再需要去重新创建一个Teacher 类(之前的一个Teacher 类只能处理一门课程),只需要实现 Course 接口,然后通过 依赖注入的方式注入到 Teacher 类中即可。
这就是多态的体现, 多态是同一个行为(上课)具有多个不同表现形式(课程)或形态的能力。
多态就是同一个接口,使用不同的实例而执行不同操作。代码搞起来:
Application.java
package com.pxl.form.versionTwo;
public class Application {
public static void main(String[] args) {
Teacher wang = new Teacher();
System.out.println("今天上什么课?");
Course c = new ExperimentCourse();
// 通过依赖注入的方式注入到 Teacher 类中
wang.Add(c);
// 会调用其重写后的 toString() 方法
wang.Answer();
System.out.println("今天上什么课?");
c = new TheoryCourse();
// 只需要注入不同的课程即可,因为每门课都实现了 Course 接口,所以只需 new 不同的 课程即可
wang.Add(c);
wang.Answer();
System.out.println("今天上什么课?");
c = new DataBaseCourse();
wang.Add(c);
wang.Answer();
System.out.println("哈哈,你可真...");
System.out.println("多态发生在哪里?");
}
}
Course
package com.pxl.form.versionTwo;
public interface Course{
}
DataBaseCourse
package com.pxl.form.versionTwo;
/**
* 实现 Course 接口,重写 toString 方法
*/
public class DataBaseCourse implements Course {
public String toString(){
String str = "上数据库课!";
return str;
}
}
ExperimentCourse
package com.pxl.form.versionTwo;
public class ExperimentCourse implements Course {
public String toString(){
String str = "上实验课!";
return str;
}
}
Teacher
package com.pxl.form.versionTwo;
public class Teacher {
// 声明一个 Course 属性
private Course course;
// 实际上是通过依赖注入的方式,调用该方法是传入的是什么课程就赋值为什么课程
public void Add(Course course){
this.course = course;
}
public void Answer(){
// 输出 对象的时候就会去调用默认的 toString 方法
System.out.println(course);
}
}
TheotyCourse
package com.pxl.form.versionTwo;
public class TheoryCourse implements Course {
public String toString(){
String str = "上理论课!";
return str;
}
}
相关代码和试验报告都已经上传到码云上,欢迎各位有兴趣的小伙伴踩点。