跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

如何通过extends关键字实现父子类继承与代码复用

Java中extends仅支持单继承,子类继承非私有成员但不继承构造器和static方法;重写需放宽访问权限、协变返回类型,并用super调用父类逻辑;字段遮蔽需用super.field访问父类字段。 Java 中
extends
的基本写法和限制 Java 里一个类只能用
extends
继承一个父类,不支持多继承。子类会自动获得父类的非私有成员(
public
、
protected
、包内默认访问权限的字段和方法),但
private
成员不可直接访问。 常见错误是误以为
extends
能继承构造器——它不能。子类必须显式或隐式调用父类构造器,否则编译报错:
Implicit super constructor xxx() is undefined
。 若父类只有带参构造器,子类构造器第一行必须写
super(...)
子类不能继承父类的
static
方法,但可以同名“隐藏”(不是重写)
final
类不能被
extends
,比如
String
或你自己加了
final
的类 重写(Override)时
super
和访问修饰符的关键细节 子类重写父类方法时,访问权限不能比父类更严格:比如父类是
protected
,子类不能改成
private
;但可以更宽松(如改为
public
)。返回类型需兼容(协变返回类型允许子类返回更具体的类型)。 容易忽略的是:重写时若想复用父类逻辑,必须用
super.methodName()
显式调用,而不是直接写方法名——后者会触发递归调用自己,导致栈溢出。 重写
toString()
、
equals(Object)
、
hashCode()
时,建议先用
super.toString()
拼接,避免丢掉父类状态 重写
clone()
时,若父类已实现深拷贝逻辑,应调用
super.clone()
再处理子类字段 没加
@Override
注解时,拼错方法名(比如
hashcode()
)不会报错,但实际没重写成功 字段遮蔽(Field Hiding)与
this
/
super
的区分 当子类声明了和父类同名的字段(无论类型是否相同),会发生字段遮蔽:子类实例中存在两份独立字段,访问时取决于引用类型。例如
Parent p = new Child(); p.field
取的是父类字段值;而
Child c = new Child(); c.field
取的是子类字段值。 这种设计极易引发 bug,因为看起来像“覆盖”,实则毫无关系。调试时如果发现字段值“莫名其妙没变”,大概率是字段遮蔽 + 忘记用
super.field
访问父类版本。 子类方法中访问同名字段,默认是
this.field
,即子类自己的字段 要明确读取父类字段,必须写
super.field
(前提是父类字段不是
private
) 字段不应被设计为可继承扩展点,优先用 getter/setter +
protected
方法暴露行为 接口实现与
extends
的混用场景 类定义里
extends
只能出现一次(指定父类),但可以同时用
implements
接多个接口。注意语法顺序:
class A extends B implements C, D
——
extends
必须在
implements
前。 当父类已实现某个接口方法,子类继承后自动具备该能力;但如果子类需要改变行为,仍需重写,此时父类实现只是默认逻辑,不是强制约束。 父类实现了
Comparable
,子类不必再
implements Comparable
,但可重写
compareTo()
若父类方法抛出异常
IOException
,子类重写时只能缩小异常范围(如不抛、或只抛
FileNotFoundException
),不能扩大 泛型父类如
class Box extends Container
,子类可固定类型:
class StringBox extends Box
字段遮蔽和构造器链是最常踩的坑,尤其在多人协作或重构时,看似安全的字段命名可能悄悄破坏父类语义。别依赖字段继承,把状态封装进受控的方法里更可靠。

相关文章