Java 抽象类详细教学

1. 什么是抽象类?

抽象类(Abstract Class)是 Java 面向对象编程中的一种特殊类,它不能被实例化,只能被继承。抽象类的主要作用是作为父类,为子类提供通用的属性和方法,同时规定某些必须由子类实现的方法。

关键点:

  • 不能实例化new 关键字不能用于抽象类)。
  • 可以包含抽象方法(没有方法体的方法)。
  • 可以包含普通方法(有方法体的方法)。
  • 子类必须实现抽象方法,否则子类也必须声明为抽象类。

2. 抽象类的定义

使用 abstract 关键字定义一个抽象类,例如:

1
2
3
4
5
6
7
8
9
10
// 抽象类 Animal
abstract class Animal {
// 抽象方法(没有方法体,子类必须实现)
abstract void makeSound();

// 具体方法(有方法体,子类可直接使用或重写)
void sleep() {
System.out.println("Sleeping...");
}
}

3. 抽象类的子类

如果一个类继承了抽象类,必须实现其所有抽象方法,否则该类也必须声明为抽象类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 具体子类 Dog 继承抽象类 Animal
class Dog extends Animal {
@Override
void makeSound() {
System.out.println("Dog barks");
}
}

public class TestAbstractClass {
public static void main(String[] args) {
// 不能直接创建抽象类对象
// Animal a = new Animal(); // 错误!

// 可以使用多态创建子类对象
Animal myDog = new Dog();
myDog.makeSound(); // 输出:Dog barks
myDog.sleep(); // 输出:Sleeping...
}
}

4. 抽象类的特点

  1. 抽象类可以包含普通方法,子类可以直接使用或选择重写。
  2. 抽象类可以包含构造方法,子类可以调用父类的构造方法来初始化父类的成员变量。
  3. 抽象类可以有成员变量,并且子类可以继承。
  4. 抽象类可以包含 static 方法,但静态方法不能是抽象方法。
  5. 一个类如果继承抽象类,必须实现所有抽象方法,否则该类也需要声明为抽象类。

5. 代码示例:抽象类与构造方法

抽象类可以有构造方法,并且子类可以调用它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
abstract class Animal {
String name;

// 构造方法
public Animal(String name) {
this.name = name;
}

// 抽象方法
abstract void makeSound();

// 普通方法
void showName() {
System.out.println("Animal name: " + name);
}
}

// 子类
class Cat extends Animal {
public Cat(String name) {
super(name); // 调用父类构造方法
}

@Override
void makeSound() {
System.out.println(name + " meows");
}
}

public class TestAbstract {
public static void main(String[] args) {
Animal myCat = new Cat("Kitty");
myCat.showName(); // 输出:Animal name: Kitty
myCat.makeSound(); // 输出:Kitty meows
}
}

6. 抽象类 vs 接口

比较项 抽象类 接口
关键字 abstract class interface
方法 既可以有抽象方法,也可以有具体方法。 只能有 public 默认的抽象方法(Java 8+ 允许 defaultstatic 方法)
成员变量 可以有成员变量 只能有 public static final 常量
构造方法 可以有构造方法 不能有构造方法
继承 只能单继承 可以多实现多个接口

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 抽象类
abstract class Animal {
abstract void makeSound();
}

// 接口
interface Flyable {
void fly();
}

// 继承抽象类并实现接口
class Bird extends Animal implements Flyable {
@Override
void makeSound() {
System.out.println("Bird chirps");
}

@Override
public void fly() {
System.out.println("Bird flies");
}
}

public class Test {
public static void main(String[] args) {
Bird b = new Bird();
b.makeSound(); // 输出:Bird chirps
b.fly(); // 输出:Bird flies
}
}

7. 抽象类的应用场景

  1. 模板设计模式(Template Method Pattern):父类提供基本结构,子类实现具体逻辑。
  2. 代码复用:抽象类可以封装公共逻辑,提高代码复用性。
  3. 限制子类必须实现某些方法:确保子类提供特定功能。

示例:模板模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
abstract class CoffeeTemplate {
// 模板方法
public final void prepareCoffee() {
boilWater();
brew();
pourInCup();
addCondiments();
}

void boilWater() {
System.out.println("Boiling water...");
}

abstract void brew();

void pourInCup() {
System.out.println("Pouring into cup...");
}

abstract void addCondiments();
}

// 具体子类
class BlackCoffee extends CoffeeTemplate {
@Override
void brew() {
System.out.println("Brewing black coffee");
}

@Override
void addCondiments() {
System.out.println("Adding sugar and milk");
}
}

public class CoffeeTest {
public static void main(String[] args) {
CoffeeTemplate coffee = new BlackCoffee();
coffee.prepareCoffee();
}
}

输出:

1
2
3
4
Boiling water...
Brewing black coffee
Pouring into cup...
Adding sugar and milk

8. 关键总结

  • 抽象类不能实例化,但可以包含构造方法和普通方法。
  • 子类必须实现抽象方法,否则子类也必须声明为抽象类。
  • 抽象类适用于具有共同行为但部分实现不同的情况(如动物类)。
  • 如果所有方法都是抽象的,建议使用接口代替抽象类
  • 模板方法模式是抽象类的典型应用,它规定子类必须实现的逻辑。

掌握 Java 抽象类,可以帮助你写出更加模块化、可扩展的代码,提高代码的复用性和可维护性! 🎯