Java 继承

继承是面向对象三大特性之一:子类可以复用父类的属性和方法,并在此基础上扩展或改写。它让代码"一次编写、处处复用",也让类与类之间形成清晰的层次。本节重点讲清 extends 语法、super 的用法,以及继承中的构造链。

extends 语法

用 extends 关键字让一个类继承另一个类:被继承的叫父类,继承者叫子类。子类自动拥有父类非 private 的成员:

class Animal {                          // 父类
    void eat() { System.out.println("吃东西"); }
}
class Dog extends Animal {              // 子类
    void bark() { System.out.println("汪汪叫"); }
}

// —— 片段需放进 main 方法中运行 ——
Dog d = new Dog();
d.eat();                                // 父类方法直接可用
d.bark();
// 输出:吃东西
// 输出:汪汪叫

继承的特性

  • 单继承:一个类只能有一个直接父类,extends 跟两个类会编译报错。
  • 传递性:A 继承 B、B 继承 C,则 A 拥有 B、C 的全部可继承成员。
  • Object 根类:任何类都直接或间接继承 java.lang.Object,自带 toString()、equals() 等方法。
  • private 成员不参与继承,但可通过父类的公开方法间接访问。

super 与构造链

创建子类对象时,先执行父类构造、再执行子类构造,形成从 Object 到子类的"构造链"。子类构造第一行其实隐式调用了 super()(父类无参构造):

class Animal {
    Animal() { System.out.println("Animal 构造"); }
}
class Dog extends Animal {
    Dog() { System.out.println("Dog 构造"); }
}

// —— 片段需放进 main 方法中运行 ——
new Dog();                              // 先父类后子类
// 输出:Animal 构造
// 输出:Dog 构造

若父类没有无参构造,子类构造必须显式写 super(参数),且 super() 必须位于第一行,否则编译报错:

class Animal {
    Animal(String name) { System.out.println("动物:" + name); }
}
class Dog extends Animal {
    Dog() { super("旺财"); }            // 显式调用父类带参构造
}

super 调用父类方法

子类重写(Override)方法后,可以用 super.方法名() 先执行父类逻辑,再补充自己的部分:

class Animal {
    void speak() { System.out.println("动物叫"); }
}
class Dog extends Animal {
    @Override void speak() {
        super.speak();                  // 先调用父类版本
        System.out.println("狗:汪汪");
    }
}

// —— 片段需放进 main 方法中运行 ——
new Dog().speak();
// 输出:动物叫
// 输出:狗:汪汪

protected 访问

protected 成员在同包内任何类都能访问;跨包时只有子类内部可访问,外部对象不行。它适合"留给子类扩展、不让外人乱动"的成员。

组合与继承怎么选

继承表示 is-a(狗是一种动物),组合表示 has-a(汽车有一台引擎)。组合更灵活、耦合更低,应优先考虑;只有确实是 is-a 且要复用父类接口时才用继承。

super 贯穿继承始终:super() 串起从父类到子类的构造链,super.方法() 复用父类实现。弄清构造顺序与重写规则,继承才能帮你写出清晰、可扩展的类体系。

笔记加载中…