Inheritance: extends, super, and overriding · 继承:extends、super 与重写
Inheritance: building on a class
- Inheritance lets one class reuse another class's fields and methods.
- The class you build on is the superclass (parent); the new class is the subclass (child).
- A subclass is-a kind of its superclass: a
Dogis anAnimal.
继承:在一个类的基础上扩展
- 继承(inheritance)让一个类复用另一个类的字段和方法。
- 被扩展的类是父类/超类(superclass);新建的类是子类(subclass)。
- 子类是一种(is-a)它的父类:
Dog(狗)是一种Animal(动物)。
extends and super
- Write
class Dog extends Animalto makeDoga subclass ofAnimal. Dogautomatically gets every public method ofAnimal, likegetName().- The subclass constructor calls the superclass constructor first with
super(...).
extends 和 super
- 写
class Dog extends Animal,就让Dog成为Animal的子类。 Dog会自动得到Animal的每个公有方法,比如getName()。- 子类的构造方法先用
super(...)调用父类的构造方法。
public class Main {
public static void main(String[] args) {
Dog d = new Dog("Rex");
System.out.println(d.getName()); // Rex (inherited from Animal)
System.out.println(d.speak()); // Woof (Dog's own version)
}
}
class Animal {
private String name;
public Animal(String name) { this.name = name; }
public String getName() { return this.name; }
public String speak() { return "some sound"; }
}
class Dog extends Animal {
public Dog(String name) {
super(name); // run Animal's constructor
}
public String speak() { // override Animal's speak()
return "Woof";
}
}
Overriding a method
- A subclass can override an inherited method: give it the same signature, a new body.
Dog'sspeak()replacesAnimal'sspeak()forDogobjects.- Methods it does not override (like
getName()) are still inherited unchanged.
重写一个方法
- 子类可以重写(override)一个继承来的方法:用相同的签名,换一个新的方法体。
Dog的speak()对Dog对象来说,替换掉了Animal的speak()。- 它没有重写的方法(比如
getName())仍然原样继承下来。
super.method() — extend, don't replace
- Sometimes you want the parent's work plus a little more.
- Inside an override,
super.describe()runs the superclass version of the method. - Then you add to its result instead of rewriting it from scratch.
super.method() —— 扩展,而不是替换
- 有时你想要父类的成果,再加上一点点。
- 在重写里面,
super.describe()会运行父类版本的方法。 - 然后你在它的结果上添加,而不用从头重写。
public class Main {
public static void main(String[] args) {
Bird b = new Bird("Tweety");
System.out.println(b.describe());
// I am an animal named Tweety, and I can fly
}
}
class Animal {
private String name;
public Animal(String name) { this.name = name; }
public String describe() { return "I am an animal named " + this.name; }
}
class Bird extends Animal {
public Bird(String name) { super(name); }
public String describe() {
return super.describe() + ", and I can fly"; // reuse, then add
}
}
is-a: a subclass fits where its superclass is expected
- Because a
Dogis anAnimal, you can writeAnimal a = new Dog("Spot");. - The variable's type is
Animal, but the object is really aDog. - This "is-a" rule is what makes the next lesson — polymorphism — possible.
是一种(is-a):子类能用在需要父类的地方
- 因为
Dog是一种Animal,你可以写Animal a = new Dog("Spot");。 - 变量的类型是
Animal,但对象其实是一个Dog。 - 这条 "is-a" 规则正是下一课多态(polymorphism)的基础。
Common mistakes
super(...)must be the first line of a subclass constructor.- Add
@Overrideso the compiler catches a wrong signature.
常见错误
super(...)必须是子类构造方法的第一行。- 加
@Override,让编译器抓出错误的签名。
Now you try
- Each task gives you a finished
Animalsuperclass. Write or complete the subclass below it. - A hidden Harness builds your object and checks both inherited and new behaviour.
- Press Run to compile, then Check answer. Your code runs on the server, so even the first run is fast.
现在轮到你
- 每个任务都给你一个写好的
Animal父类。请在它下面写出或补全子类。 - 一个隐藏的 Harness(检查程序)会创建你的对象,检查继承来的行为和新增的行为。
- 按 Run 编译,然后 Check answer。你的代码在服务器上运行,所以第一次运行也很快。
Below the finished Animal, write a class Cat that extends Animal. Give it a constructor Cat(String name) that passes the name up with super(name). Add nothing else — Cat should inherit getName() for free. · 在写好的 Animal 下面,写一个 继承自 Animal 的类 Cat。给它一个构造方法 Cat(String name),用 super(name) 把名字传上去。不要加别的 —— Cat 应该免费继承到 getName()。
Click Run to see the output here. · 点击“运行”查看此处输出。
Complete the class Cow (it already extends Animal). Override speak() so a Cow returns · 返回值 "Moo" instead of the default. getName() must still work (inherited). · 完成类 Cow(它已经继承自 Animal)。重写 speak(),让 Cow 返回 "Moo",而不是默认值。getName() 仍然要能用(继承来的)。
Click Run to see the output here. · 点击“运行”查看此处输出。
Complete the class Fish (it already extends Animal). Override describe() so it returns the Animal description plus ", and I can swim". Reuse the parent's work by calling super.describe() — do not rewrite the whole sentence. · 完成类 Fish(它已经继承自 Animal)。重写 describe(),让它返回 Animal 的描述再加上 ", and I can swim"。通过调用 super.describe() 复用父类的成果 —— 不要把整句重写一遍。
Click Run to see the output here. · 点击“运行”查看此处输出。