抽象类和接口都是用来「定义规范、让子类去实现」的。
1. 抽象类
用 abstract 修饰的类。抽象类里可以有抽象方法(没有方法体)。
1 2 3 4 5 6 7 8 9 10
| public abstract class Shape { abstract double area();
public void print() { System.out.println("这是一个形状"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class Circle extends Shape { double r;
public Circle(double r) { this.r = r; }
@Override double area() { return Math.PI * r * r; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class Rectangle extends Shape { double width; double height;
public Rectangle(double width, double height) { this.width = width; this.height = height; }
@Override double area() { return width * height; } }
|
1 2 3 4 5 6 7 8 9 10 11
| public class Main { public static void main(String[] args) {
Shape c = new Circle(2); System.out.println(c.area());
Shape r = new Rectangle(3, 4); System.out.println(r.area()); } }
|
要点:
- 抽象类不能实例化(不能
new)
- 子类继承抽象类,必须实现所有抽象方法,否则子类也得是抽象类
2. 接口
接口用 interface 定义,是一组方法的「契约」。类用 implements 实现接口。
1 2 3 4
| public interface Flyable { void fly(); }
|
1 2 3
| public interface Swimmable { void swim(); }
|
1 2 3 4 5 6 7 8 9 10 11 12
| public class Duck implements Flyable, Swimmable { @Override public void fly() { System.out.println("鸭子在飞"); }
@Override public void swim() { System.out.println("鸭子在游泳"); } }
|
1 2 3 4 5 6 7 8 9 10 11
| public class Main { public static void main(String[] args) { Duck duck = new Duck(); duck.fly(); duck.swim();
Flyable f = new Duck(); f.fly(); } }
|
要点:
- 接口方法默认
public abstract
- 一个类可以实现多个接口(弥补单继承的限制)
3. 接口的默认方法和静态方法(JDK 8+)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public interface Greeting { void sayHi();
default void sayBye() { System.out.println("再见"); }
static void info() { System.out.println("这是一个问候接口"); } }
|
1 2 3 4 5 6
| public class Person implements Greeting { @Override public void sayHi() { System.out.println("你好"); } }
|
1 2 3 4 5 6 7 8 9
| public class Main { public static void main(String[] args) { Person p = new Person(); p.sayHi(); p.sayBye();
Greeting.info(); } }
|
4. 抽象类和接口的区别
| 对比项 |
抽象类 |
接口 |
| 继承/实现 |
单继承(extends) |
可实现多个(implements) |
| 方法 |
可以有抽象方法,也可以有普通方法 |
默认是抽象方法,JDK 8 起有默认/静态方法 |
| 字段 |
可以有实例字段 |
只能有常量(public static final) |
| 语义 |
“是什么”(is-a) |
“能做什么”(has-a / can-do) |
选择建议:
- 表示「是什么」的继承关系,用抽象类(如
Dog 是 Animal)
- 表示「具备什么能力」,用接口(如
Duck 能 Flyable、能 Swimmable)
小结
- 抽象类:
abstract 修饰,不能实例化,子类必须实现抽象方法
- 接口:
interface 定义规范,implements 实现,一个类可实现多个接口
- 抽象类表示「是什么」,接口表示「能做什么」