Java 中的 super
在子类构造器里使用 super,让父类构造器先运行。保持 Truck extends Car。在 Truck() 里先调用 super();,再打印 truck。在 Car() 里打印 car。编译 Yard.java 并运行 java Yard。屏幕应先显示 car,再显示 truck。第二个演示用 super("car") 把标记传给 Car(String mark)。把方法覆盖留给下一页——本课讲的是带 super 的构造器顺序。
先调用父类构造器
继承页让空的 Truck 使用 Car 上的 horn。本页加上构造器。打开 Yard.java。保持 public 类名为 Yard。删除残留的路径演示、若会混淆构造器的仅含 horn 的文件、Store 写入器,以及任何键盘 Scanner。程序不应等待输入。不需要 import 行。
声明带无参构造器的父类,让它打印 car:
class Car {
Car() {
System.out.println("car");
}
}
用 extends Car 声明子类。在 Truck() 里把 super(); 作为第一条语句,然后打印 truck:
super();
System.out.println("truck");
在 Yard.main 里创建一个 truck:
Truck t = new Truck();
创建 truck 会进入 Truck()。该调用以 super() 开始,从而运行 Car()。父类结束后,子类打印才运行。
class Car {
Car() {
System.out.println("car");
}
}
class Truck extends Car {
Truck() {
super();
System.out.println("truck");
}
}
public class Yard {
public static void main(String[] args) {
Truck t = new Truck();
}
}
在存放 Yard.java 的文件夹里运行 javac Yard.java。括号、花括号和分号配对正确时,javac 不会自己打印一行。然后运行 java Yard——不是 java Yard.java。运行命令不要带 .java 后缀。文件里只保留一个 public 类,使类名与 Yard 一致。辅助类型 Car 和 Truck 在这种初学者写法里不带 public。
屏幕显示 car,然后是 truck。走一遍运行。Java 从 Yard.main 开始。new Truck() 进入 Truck()。第一条语句是 super();,因此 Car() 运行并打印 car。控制回到 Truck(),再打印 truck。父类那一行出现在子类那一行之前,因为 super() 先运行。
看着屏幕把顺序说出来:父类构造器,然后是子类打印。这个口头顺序就是 super() 在子类构造器里强制的顺序。如果两行顺序错了,重新打开教学文件,确认 super(); 仍是 Truck() 里任何 println 之前的第一条语句。
若在之后父构造器需要参数的实验里先打印 truck 再写 super(),javac 可能拒绝——你写 super 时它必须是第一条语句。本课第一个演示里父类不需要参数,教学文件故意把 super(); 放在最前,好让顺序清楚。若只看到旧 horn 演示的 beep,切到构造器教学文件并重新运行 java Yard。
此页不要在 Truck 上重写 horn。覆盖方法是下一课。今天子类构造器用 super 与父类对话,再打印自己的词。把 car 留在父类一侧,把 truck 留在子类一侧,让每一行都说明哪个构造器结束了。
用 super 把值传给父类
第二个程序仍保留 extends。父类构造器现在接受 String mark 并打印该标记。子类调用 super("car"),然后打印 truck。
class Car {
Car(String mark) {
System.out.println(mark);
}
}
class Truck extends Car {
Truck() {
super("car");
System.out.println("truck");
}
}
public class Yard {
public static void main(String[] args) {
Truck t = new Truck();
}
}
用 javac Yard.java 编译,然后运行 java Yard。屏幕再次显示 car,然后是 truck。这次 car 是你通过 super("car") 传入的参数,而不是无参 Car() 里写死的打印。子类选择了标记字符串;父类构造器把它打印出来。之后子类打印 truck。
再读一次父类构造器签名:Car(String mark)。super("car") 里引号中的字符串就是那个 mark。这次检查不要改文件其他部分——保持 extends Car,保持子类打印 truck,保持 main 里的 new Truck()。屏幕仍以 car 下面的 truck 结束,因为子类打印只在 super("car") 返回之后才运行。
若在 Car 只有 Car(String mark) 时省略 super("car"),javac 会拒绝,因为父类不再有可替你调用的静默无参构造器。写出匹配的 super(...) 调用,就是子类用所需值启动父类的方式。把 super 保持为 Truck() 里的第一条语句。若 javac 抱怨 Car 缺少默认构造器,先看子类构造器,确认 super("car") 行存在且仍是第一条。
与 horn 页上的普通 extends 对比
在继承页上,空的 Truck 没有写构造器就调用了 horn。在本页,构造器通过 super 按顺序运行。若附近还有 horn 演示,可当作历史保留;用 java Yard 运行 super 教学文件,让屏幕显示 car 然后 truck。
horn 页证明了 extends 会共享方法。本页证明 extends 也共享构造路径:子类通过 super 启动父类,再继续自己的打印。两课都保持 Truck extends Car。只有 Truck 的体在变——从带后续 horn 调用的空花括号,变成以 super 开头的构造器。
super()、super("car") 和构造器顺序是新记号。你仍然需要 extends。你还不必覆盖方法。若 main 里还留着 horn 调用,为本演示删掉它,让屏幕只显示构造器打印。
本页给 override 留下什么
本页用 super 运行父类构造器。下一页讲 override:子类为自己写父类已有方法的版本。这里先停留在构造器里的 super 调用。暂时不要把在 Truck 上替换 horn 当作这些演示的要求。
以后覆盖方法时,你往往仍会先用 super 调用父类构造器。把本页当作那个故事的构造器一半。把两个 Yard 演示做到 car 然后 truck 感觉自然,再打开 override 课。
进入 override 之前
你可以调用 super(); 再打印 truck,并先看到 car。当父类接受 mark 时,你可以调用 super("car"),仍看到 car,然后是 truck。对每个保留的演示依次编译 Yard.java 并运行 java Yard。父类构造器在子类打印之前结束。下一页是 override,子类替换方法体。
保留无参 super() 演示以看清顺序。保留 super("car") 演示以看清传参。把方法覆盖留在本页之外。这三条习惯是继续前进前的检查点。当 new Truck() 之后 car 出现在 truck 上方时,super 完成本课任务,你已准备好进入关于 override 的下一主题。
最后再看一遍文件夹:一个 public Yard、两个辅助类型、没有键盘等待、没有路径残留、没有强制重写 horn。对你打开的演示再跑一次 javac Yard.java 和 java Yard。若屏幕仍打印 car 然后 truck,构造器顺序就稳了,课程可以在下一页进入 override。
🧠 测试您的知识
测试您的知识
通过这个互动测验挑战自己,看看你对这个主题的理解程度如何
📝 说明
- 仔细阅读每个问题
- 为每个问题选择最佳答案
- 您可以随时重新参加测验
- 您的进度将显示在顶部