Java继承必须用extends关键字,单继承且默认继承Object;子类通过访问修饰符决定能否访问父类成员,同名时用super指向父类;构造器不继承但必须调用,重写必须加@Override防错。

继承用 extends 关键字声明,不是可选项而是语法硬要求
Java 中实现继承的唯一合法方式是使用 extends 关键字,写在子类定义的 class 声明后、左大括号前。没有它,就不是继承关系;哪怕两个类结构再像,也不会自动产生父子关系。
常见错误现象:
– 忘写 extends,误以为“属性一样就是继承”;
– 在接口实现中错用 extends(该用 implements);
– 父类用了 final 修饰,却仍尝试继承,编译直接报错 Cannot inherit from final 'XXX'。
必须注意:
– 一个类只能 extends 一个父类(不支持多继承);
– 如果没显式写 extends,该类默认继承 java.lang.Object;
– extends 后面只能跟一个类名,不能跟多个,也不能跟接口。
子类能访问哪些父类成员?关键看访问修饰符和 super 的使用场景
子类不是“复制”父类代码,而是获得对父类非私有成员的访问权限。能否访问,取决于父类成员的修饰符:
-
public:子类可直接调用,无需super -
protected:子类可直接访问(即使跨包),推荐用于需要被继承但不想对外公开的字段/方法 - 默认(包访问):仅限同一包内子类可访问
-
private:子类完全不可见,哪怕同名字段也属于独立变量(此时就近访问子类自己的)
当子类和父类存在同名成员时,super 是唯一明确指向父类版本的手段:
class Parent { String name = "Parent"; }
class Child extends Parent {
String name = "Child";
void print() {
System.out.println(name); // 输出 "Child"
System.out.println(super.name); // 输出 "Parent"
}
}
构造方法不会被继承,但必须参与初始化链
子类实例化时,JVM 强制要求先完成父类部分的初始化——这意味着:构造方法虽不被继承,但必须被调用。
立即学习“Java免费学习笔记(深入)”;
实操要点:
– 若父类只有带参构造方法,子类构造器第一行必须显式写 super(...),否则编译失败;
– super() 或 super(参数) 必须是子类构造方法的第一条语句;
– 不写 super(...) 时,编译器自动插入 super(),前提是父类存在无参构造器;
– 如果父类没无参构造器,又忘了写 super(...),就会报错 Implicit super constructor XXX() is undefined。
为什么重写方法要加 @Override?不只是为了好看
@Override 是编译期检查注解,核心作用是防错:它告诉编译器“我本意是覆盖父类方法”,一旦签名不符(比如参数类型写错、返回值变了),立刻报错,而不是静默创建一个新方法。
典型翻车场景:
– 父类方法是 void eat(String food),子类写成 void eat(StringFood food)(拼错参数名),没加 @Override 就变成重载而非重写,运行时父类逻辑照常执行,bug 难发现;
– 父类方法返回 String,子类重写返回 Object(不满足协变返回),加了 @Override 就会编译失败,及时暴露问题。
所以,只要意图是重写,就必须加 @Override——这是 Java 继承中最容易被跳过的安全护栏。
继承不是把父类代码“粘贴过来”,而是建立一种运行时的身份与能力委托关系。最常被忽略的点是:子类对象在内存里同时拥有父类字段副本 + 子类字段副本,而方法调用走的是动态绑定,不是静态拷贝。这点决定了为什么字段访问要靠 super,而方法调用可以靠重写和多态。








