参考资料::黑马程序员·入门到飞起上
1.1 概述
1.1.1 抽象类引入
在面向对象编程中,当父类中的方法被子类重写,且子类各自的实现方式差异较大时,父类方法的声明具有通用的指导意义,但方法主体可能不再适用于所有子类。此时,父类虽知道子类应具备某个功能,却不清楚具体的实现方式,这一实现过程应由子类自行决定。因此,父类只需提供一个没有方法体的方法定义,将具体实现留给子类,这种没有方法体的方法被称为抽象方法,在Java语法中,包含抽象方法的类即为抽象类。
- 抽象方法:指的是仅有方法声明,而无方法体的方法。
- 抽象类:包含抽象方法的类被定义为抽象类。
1.2 abstract使用格式
“abstract”在Java中表示抽象的含义,可用于修饰方法和类。当修饰方法时,该方法成为抽象方法;修饰类时,该类则成为抽象类。
1.2.1 抽象方法
使用abstract关键字修饰方法,该方法便成为抽象方法。抽象方法仅包含方法名,不包含方法体。其定义格式如下:
修饰符 abstract 返回值类型 方法名 (参数列表);例如:
public abstract void run();1.2.2 抽象类
若一个类包含抽象方法,那么这个类必须被声明为抽象类。需要注意的是,抽象类不一定都含有抽象方法,但只要类中存在抽象方法,就必须将其定义为抽象类。抽象类的定义格式如下:
abstract class 类名字 {
}示例代码如下:
public abstract class Animal {
public abstract void run();
}1.2.3 抽象类的使用
继承抽象类的子类必须重写父类中的所有抽象方法,否则该子类同样必须声明为抽象类。以下通过具体代码示例说明:
// 父类,抽象类
abstract class Employee {
private String id;
private String name;
private double salary;
//空参构造
public Employee() {
}
//全参构造
public Employee(String id, String name, double salary) {
this.id = id;
this.name = name;
this.salary = salary;
}
// 抽象方法
// 抽象方法必须要放在抽象类中
abstract public void work();
}
// 定义一个子类继承抽象类
class Manager extends Employee {
public Manager() {
}
public Manager(String id, String name, double salary) {
super(id, name, salary);//调用父类的构造方法
}
// 2.重写父类的抽象方法
@Override
public void work() {
System.out.println("管理其他人");
}
}
// 定义一个子类继承抽象类
class Cook extends Employee {
public Cook() {
}
public Cook(String id, String name, double salary) {
super(id, name, salary);
}
@Override
public void work() {
System.out.println("厨师炒菜多加点盐...");
}
}
// 测试类
public class Demo10 {
public static void main(String[] args) {
// 创建抽象类,抽象类不能创建对象
// 假设抽象类让我们创建对象,里面的抽象方法没有方法体,无法执行.所以不让我们创建对象
// Employee e = new Employee();
// e.work();
// 3.创建子类
Manager m = new Manager();
m.work();
Cook c = new Cook("ap002", "库克", 1);
c.work();
}
}在上述代码中,子类对父类抽象方法的完整实现过程,也被称为“实现方法”。
1.3 抽象类的特征
抽象类的特征可以概括为“有得有失”:
- 有得:抽象类获得了定义抽象方法的能力,从而为子类提供了一种通用的行为规范或接口,使得子类在继承抽象类时,必须按照抽象类定义的规则实现具体的功能。
- 有失:抽象类失去了直接创建对象的能力。这是因为抽象类中可能包含未实现的抽象方法,如果允许创建抽象类的对象,在调用这些抽象方法时将无法执行具体的操作,因此Java语言禁止创建抽象类的对象。
此外,抽象类与普通类一样,具备构造方法、实例方法、静态方法等其他成员。
1.4 抽象类的细节
在使用抽象类时,有一些语法细节需要注意。这些细节无需刻意记忆,当在开发工具(如IDEA)中出现报错时,能够明白如何修改即可。理解这些细节的关键在于把握抽象类的本质。
- 抽象类不能创建对象:试图创建抽象类的对象会导致编译错误。这是因为抽象类中的抽象方法没有具体的实现,若创建对象并调用抽象方法,将无法执行有效的操作。只有其非抽象子类才能创建对象,通过子类对象调用重写后的具体方法来实现相应功能。
- 抽象类中可以有构造方法:抽象类中的构造方法主要用于供子类在创建对象时初始化父类成员。在子类的构造方法中,默认会调用
super()来访问父类的构造方法,以确保父类成员能够正确初始化。 - 抽象类不一定包含抽象方法,但有抽象方法的类必定是抽象类:即使一个抽象类中不包含抽象方法,它仍然具有存在的价值。这种情况下,抽象类的目的通常是限制调用者创建该类的对象,常用于特定的类结构设计,例如为一组相关的子类提供一个统一的抽象基类,便于进行类型管理和多态操作。
- 抽象类的子类必须重写抽象父类中的所有抽象方法:否则,子类必须也定义为抽象类,否则会导致编译错误。这是因为如果子类不重写所有抽象方法,那么该子类可能仍然包含抽象方法,创建此类对象并调用抽象方法将没有实际意义。通过强制子类重写抽象方法,保证了子类具有具体的行为实现。
- 抽象类存在的意义是为了被子类继承:抽象类定义了一组子类共同遵循的模板,其中已经实现的部分是模板中确定的成员,而对于不确定如何实现的部分,则定义成抽象方法,由具体的子类根据自身需求去实现。这样可以提高代码的复用性和可扩展性,同时确保子类之间具有一定的一致性和规范性。
1.5 抽象类存在的意义
抽象类存在的核心意义在于为子类提供一个可继承的基础框架,强制子类按照特定的格式进行方法重写。通过抽象类,我们可以将一些具有共性的行为和属性抽象出来,避免在子类中重复实现,提高代码的复用性。同时,抽象类定义的抽象方法为子类提供了明确的行为规范,使得不同的子类能够以统一的方式进行操作,增强了代码的可维护性和扩展性。如果没有子类继承,抽象类的存在将失去实际意义。
















