抽象与接口
abstraction、interfaces、nested-classes。
30 分钟
抽象与接口
java-inheritance 已讲继承——本课深化 抽象类、接口、default 方法、嵌套类,在「复用」与「解耦」之间做正确选型。
学习目标
- 区分 abstract class 与 interface 的适用场景
- 使用接口 default/static 方法组织 API
- 用静态/内部类表达紧密耦合的辅助类型
抽象类 vs 接口
| abstract class | interface | |
|---|---|---|
| 实例字段 | 可以有 | 只有 public static final 常量 |
| 构造器 | 有 | 无 |
| 多继承 | 单继承 | 类可实现多接口 |
| 典型用途 | 共享状态与模板方法 | 能力契约、策略 |
public abstract class AbstractLesson {
protected final String slug;
protected AbstractLesson(String slug) {
this.slug = slug;
}
public abstract String renderHtml();
}
public interface Publishable {
boolean isPublished();
default void publish() {
throw new UnsupportedOperationException();
}
}
public class MarkdownLesson extends AbstractLesson implements Publishable {
private boolean published;
public MarkdownLesson(String slug) { super(slug); }
@Override
public String renderHtml() { return "<article>" + slug + "</article>"; }
@Override
public boolean isPublished() { return published; }
}
选型口诀:IS-A 且共享代码 → 抽象类;CAN-DO 能力 → 接口。
嵌套类
public class TrackCatalog {
private final Map<String, Lesson> bySlug = new HashMap<>();
public Iterator<Lesson> iterator() {
return new LessonIterator();
}
private class LessonIterator implements Iterator<Lesson> {
private final Iterator<Lesson> delegate = bySlug.values().iterator();
@Override public boolean hasNext() { return delegate.hasNext(); }
@Override public Lesson next() { return delegate.next(); }
}
public static final class Builder {
private String slug;
public Builder slug(String slug) { this.slug = slug; return this; }
public TrackCatalog build() { return new TrackCatalog(slug); }
}
}
- 内部类 持有外部类引用,可访问外部私有成员
- static 嵌套类 不持有外部引用,常用作 Builder
- 匿名类 已被 Lambda 大量取代(见 )