1. 继承机制深度解析
1.1 继承的本质与实现
在Java中,继承是通过extends关键字实现的父子类关系。这种机制允许子类自动获取父类的属性和行为,是代码复用的重要手段。我见过不少初学者容易混淆继承与接口实现,这里有个简单的记忆方法:继承描述的是"是什么"的关系(如Dog是Animal),而接口描述的是"能做什么"的能力。
创建继承关系的基本语法:
java复制public class Parent {
// 父类成员
}
public class Child extends Parent {
// 子类特有成员
}
关键提示:良好的继承设计应该遵循LSP原则(里氏替换原则),即任何使用父类对象的地方都应该能够透明地替换为子类对象而不影响程序正确性。
1.2 成员继承范围详解
子类继承父类成员时,权限修饰符起着决定性作用:
- private:完全不可见(即使通过反射访问也存在安全隐患)
- 缺省(包私有):同包内可见
- protected:同包+子类可见
- public:全局可见
实际开发中,我建议:
- 成员变量尽量用private,通过protected方法提供访问
- 需要被子类重写的方法用protected
- 对外公开的接口用public
1.3 构造器调用链
子类实例化时的构造过程很有意思:
- JVM先分配对象内存空间
- 初始化父类部分(执行父类构造器)
- 最后初始化子类特有部分
这个顺序保证了对象的完整性。我曾遇到过因为忽略这个顺序导致的NPE问题:在子类构造器中直接使用父类未初始化的成员。
典型错误示例:
java复制public class Parent {
protected List<String> data;
public Parent() {
// 忘记初始化data
}
}
public class Child extends Parent {
public Child() {
data.add("test"); // NullPointerException!
}
}
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 方法重写艺术
2.1 重写规则精要
方法重写(Override)不是简单的复制粘贴,需要严格遵守以下规则:
- 方法签名必须完全相同(方法名+参数列表)
- 返回类型可以是父类方法返回类型的子类(协变返回)
- 访问权限不能更严格(可以更宽松)
- 不能抛出比父类方法更多的检查型异常
一个标准的重写示例:
java复制@Override
public String toString() {
return "CustomObject{" +
"field1=" + field1 +
", field2=" + field2 + '}';
}
2.2 重写与重载的陷阱
很多面试者分不清重写(Override)和重载(Overload):
- 重写:父子类间,相同签名
- 重载:同类/父子类间,不同签名
特别要注意的是,静态方法不存在重写!这被称为"隐藏":
java复制class Parent {
static void method() { System.out.println("Parent"); }
}
