抽象类
1. 认识抽象类
在 Java 中有一个关键字叫:abstract ,它的中文含义是"抽象",可以用它来修饰类、成员方法。
abstract 修饰类,这个类就是抽象类。
abstract 修饰方法,这个方法就是抽象方法。
2. 注意事项
- 抽象类中不一定有抽象方法,但是,有抽象方法的类一定是抽象类
- 类该有的成员(成员变量、成员方法、构造器)抽象类都可以有
- 最大的特点:抽象类不能创建对象!它仅作为一种特殊的父类,让子类继承并实现重写!
abstract class A {
private String name;
public static String schoolName = "New School";
public A() {
}
public A(String name) {
this.name = name;
}
// A类独有的方法
public String getName() {
return name;
}
// A类非独有的方法:被B类继承
public void printOut() {
System.out.println("通过'普通的模式'的继承实现多态 [from A]");
}
// "抽象方法"实现了哪些东西?
// 1. 父类不用写大括号{},以及对应的代码,因为写了也没意义,交给子类进行重构就好啦!
// 2. 强制要求子类,必须对当前的这个抽象方法进行重构,否则子类也会被同化成抽象类!
// 3. 综上所述,抽象类与抽象方法最终只是为了让子类强制执行重构,以实现更好的"多态"
// 所以,不使用抽象类来打造"多态"也是可以的,但是显得不那么专业。
public abstract void run();
// 如果使用普通的模式让子类进行重构,从而实现"多态",上面的代码则应该改成——如下所示:
// public void run(){
//
// }
}
class B extends A {
// 调用A类的构造器
public B(String name) {
super(name);
}
// B类独有的方法
public void helloWorld() {
System.out.println("Hello World");
}
// 继承A类的方法,普通的模式进行继承,实现多态
@Override
public void printOut() {
System.out.println("通过'普通的模式'的继承实现多态 [from B]");
}
// 当B类继承了A类,
// 要么选择: 将A类中的抽象方法run()进行重构,
// 要么选择: B类也变成抽象类,
// 要么选择: 程序报错!
public void run() {
System.out.println("B类: 正在跑步...");
}
}
public class HelloWorld {
public static void main(String[] args) {
// A obj = new A(); // 报错,A类是抽象类,无法创建对象
A obj = new B("Jack"); // 正常
System.out.println(obj.schoolName); // (A类的属性[或者说成员变量])
System.out.println(obj.getName()); // (A类的独有方法)
obj.printOut(); // (B类的方法:它是重写了A类的)
// obj.helloWorld(); // 报错 (B类的独有方法)
// 执行结果:
// New School
// Jack
// 通过'普通的模式'的继承实现多态 [from B]
}
}
3. 抽象类的意义
抽象类的应用场景和好处是,父类知道每个子类都要做某个行为,但是在每个子类中要做的情况不一样,父类就定义成抽象方法,交给子类去强制重写。我们抽象出这样的抽象类,就是为了更好的支持多态。
4. 抽象类的应用
4.1 模板方法设计模式
- 抽象类的常见应用场景:模板方法设计模式
- 模板方法设计模式:解决了方法中存在重复代码的问题
4.2 写法
- 定义一个抽象类
- 在里面定义两个方法
- 一个是模板方法:把需要重复使用的代码放进去
- 一个是抽象方法:具体的功能实现交给子类完成
abstract class People {
// 没有被继承的成员方法
// 像这种不需要被继承的方法,强烈建议加上 final 关键字,以防止不小心被重写了!
public final void speak() {
System.out.println("这个人正在台上演讲...");
System.out.println(speakMain());
System.out.println("这个人演讲结束啦");
}
// 抽象方法
public abstract String speakMain();
}
class Teacher extends People {
// 以Teacher风格,重写抽象方法
public String speakMain() {
return "这个人是老师,演讲的内容很有深度!";
}
}
class Student extends People {
// 以Student风格,重写抽象方法
public String speakMain() {
return "这个人是学生,在台上演讲有点紧张。";
}
}
public class Test {
public static void main(String[] args) {
People p1 = new Teacher();
People p2 = new Student();
p1.speak();
System.out.println("-------------------------");
p2.speak();
}
}
// 运行结果:
//这个人正在台上演讲...
//这个人是老师,演讲的内容很有深度!
//这个人演讲结束啦
//-------------------------
//这个人正在台上演讲...
//这个人是学生,在台上演讲有点紧张。
//这个人演讲结束啦