




Java继承实现代码复用并支撑多态,子类可直接访问父类public/protected成员,但private成员不可见;需满足“is-a”关系,否则优先用组合;final类/方法限制继承与重写,过度继承增加维护成本。
Java 中的继承最直接解决的是代码复用问题:避免在多个类中重复写相同的字段和方法。只要父类中定义了 public 或 protected 的字段、方法,子类通过 extends 就能直接访问或调用,无需重写。
常见错误是误以为 private 成员也能被继承——它们虽参与父类对象构建,但子类中不可见、不可直接访问,只能通过父类提供的 public/protected 方法间接操作。
super(),若父类无无参构造器,必须显式写 super(...)
final 类不能被继承,final 方法不能被重写,这是设计上对复用边界的控制Dog is a Animal),强行继承会导致后期维护困难继承本身不等于多态,但它为多态提供了基础结构:只有存在父子类关系,才能用父类引用指向子类对象,进而实现方法重写(@Override)后的动态分派。
典型场景是统一处理不同子类型:List 里存 Dog 和 Cat,调用 makeSound() 时自动执行各自重写的版本。没有继承,这种抽象就无法落地。
当两个类之间不存在天然的“is-a”关系,却想复用代码时,硬套继承反而破坏设计。比如 “Car 有 Engine”,不是 “Car is an Engine”,这时应该用组合(has-a)。
组合配合接口(如 Runnable、Comparable)往往比继承更松耦合、更易测试、更利于扩展。Java 8+ 接口支持默认方法,进一步削弱了为复用而继承的必要性。
每次使用 extends,不只是加了一行代码,还绑定了子类与父类的

private 成员变更(如字段改名、方法加参数、抛新异常),都可能悄无声息地破坏子类编译或运行行为。
尤其在依赖第三方库时,继承其公开类等于把它的内部演化风险引入自己的代码。这也是为什么 Spring、Guava 等主流框架大量使用 final 类 + 工厂/构建器 + 接口回调,而非鼓励用户继承。
Serializable,子类即使实现了也会抛 NotSerializableException
getDeclaredMethods() 不包含父类方法,需手动遍历 getSuperclass()