抽象类与接口
抽象类和接口都是"制定规范、延迟实现"的机制,是设计可扩展代码的核心工具。
抽象类
用 abstract 修饰的类,不能直接实例化,通常作为基类抽取公共代码:
public abstract class Shape {
String name;
// 抽象方法:只有声明,由子类实现
public abstract double area();
// 普通方法:子类直接复用
public void show() {
System.out.println(name + " 的面积是 " + area());
}
}
public class Circle extends Shape {
double r;
public Circle(double r) {
this.name = "圆";
this.r = r;
}
@Override
public double area() {
return Math.PI * r * r;
}
}
| 特点 | 说明 |
|---|---|
| 实例化 | 不能 new Shape() |
| 抽象方法 | 有抽象方法的类必须是抽象类 |
| 普通成员 | 可以有成员变量、构造方法、普通方法 |
| 继承 | 子类必须实现所有抽象方法,否则子类也得是抽象类 |
接口
用 interface 定义,描述"能做什么"的能力规范。类用 implements 实现接口,且可以实现多个:
public interface Flyable {
void fly(); // 接口方法默认 public abstract
}
public interface Swimmable {
void swim();
}
public class Duck implements Flyable, Swimmable {
@Override
public void fly() {
System.out.println("鸭子扑腾着飞");
}
@Override
public void swim() {
System.out.println("鸭子划水");
}
}
接口中的变量默认是 public static final(常量)。Java 8 起接口可以有 default 默认方法:
public interface Greeting {
default void hello() {
System.out.println("你好");
}
}
抽象类 vs 接口
| 对比项 | 抽象类 | 接口 |
|---|---|---|
| 关键字 | abstract class | interface |
| 继承/实现 | 单继承 extends | 多实现 implements |
| 成员变量 | 任意 | 只能是常量 |
| 构造方法 | 有 | 没有 |
| 设计语义 | "是什么"(is-a) | "能做什么"(has-a 能力) |
经验法则:表达同类事物的共性用抽象类,表达跨类别的能力用接口。