Java不支持多继承,extends只能指定一个父类;子类构造方法必须显式调用super()(若父类无无参构造);重写方法需遵守契约,慎用强制转换,类型安全依赖编译检查与instanceof运行时验证。

Java里extends只能写一个类,没得商量
Java不支持多继承,extends后面只能跟一个父类。这不是语法限制松动的问题,是语言设计铁律——编译器直接报错,不会给你运行机会。
常见错误现象:error: class X inherits from more than one class(实际错误信息更接近error: '{' expected或duplicate class,但根源就是写了两个extends)。
- 想复用多个类的行为?用
implements接口,不是extends - 父类本身已
extends了别的类?没关系,子类只管写自己的extends,继承链自动拉通 - 误把接口当类写在
extends后?编译报错:error: incompatible types: A cannot be converted to Class
子类构造方法里super()不是可选的,是默认存在的
只要父类没有无参构造方法,子类所有构造方法都必须显式调用super(...),否则编译失败。
使用场景:父类构造器带参数(比如public Person(String name)),子类new Student("张三", 101)时,必须先告诉父类怎么初始化name字段。
立即学习“Java免费学习笔记(深入)”;
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 没写
super(),且父类无无参构造 → 编译报错:error: constructor X in class X cannot be applied to given types -
super()必须是构造方法第一行,否则报错:error: call to super must be first statement in constructor - 如果父类只有
protected或private构造方法,子类无法继承(除非在同一包或子类是内部类)
重写toString()、equals()这些方法前,先确认父类有没有做有用的事
不是所有继承都需要重写;盲目覆盖反而破坏父类契约。比如java.time.LocalDate已经实现健壮的equals(),你继承它再重写就大概率出错。
性能影响:重写hashCode()但没同步改equals(),或者反之,会导致HashMap查不到对象——这种bug很难定位。
- 用
@Override注解,避免拼错方法名(比如写成toStirng())导致编译通过但逻辑失效 - IDE自动生成的
equals()常包含getClass() != obj.getClass()判断,这会阻止子类实例和父类实例相等——如果业务需要“Liskov替换”,就得改成instanceof - 父类字段被
private封装?子类重写toString()时无法直接访问,得靠public/protectedgetter
子类引用指向父类实例?编译直接拦住,别试了
Animal a = new Dog();合法;但Dog d = new Animal();编译报错:error: incompatible types: Animal cannot be converted to Dog。这是类型系统的基本防线。
容易踩的坑:以为加个强制转换(Dog)new Animal()就能过——能编译,但运行时抛ClassCastException。
- 运行时类型检查用
instanceof,不是靠猜:“if (a instanceof Dog) { Dog d = (Dog)a; … }” - 泛型擦除后,
List<dog></dog>和List<animal></animal>不兼容,不能用extends继承来绕过(那是? extends Animal的事) - Spring等框架返回
Object再强转?务必先instanceof,否则线上突然崩
继承不是为了“看起来像”,而是为了“能替代”。父类方法签名、异常声明、返回值协变规则,每一条都在约束你能怎么写——写歪了,编译器第一个不答应。

















