Jon*_*nny 7 java coding-style super
我试图在Java中获得继承权,并且已经了解到当在子类中重写方法(和隐藏字段)时,仍然可以使用"super"关键字从超类中访问它们.
我想知道的是,'super'关键字是否应该用于非重写方法?
有没有区别(对于非重写方法/非隐藏字段)?
我在下面举了一个例子.
public class Vehicle {
private int tyreCost;
public Vehicle(int tyreCost) {
this.tyreCost = tyreCost;
}
public int getTyreCost() {
return tyreCost;
}
}
Run Code Online (Sandbox Code Playgroud)
和
public class Car extends Vehicle {
private int wheelCount;
public Vehicle(int tyreCost, int wheelCount) {
super(tyreCost);
this.wheelCount = wheelCount;
}
public int getTotalTyreReplacementCost() {
return getTyreCost() * wheelCount;
}
}
Run Code Online (Sandbox Code Playgroud)
具体来说,既然getTyreCost()没有被覆盖,应该getTotalTyreReplacementCost()使用getTyreCost(),还是super.getTyreCost()?
我想知道是否应该在访问超类的字段或方法的所有实例中使用super(在代码中显示您正在访问超类),或者仅在重写/隐藏的那些实例中使用super(因此它们脱颖而出).
Ric*_*uen 11
不要使用super关键字来引用其他未被覆盖的方法.这使得其他试图扩展您的类的开发人员感到困惑.
让我们来看看一些代码,不使用super关键字用这种方式.这里有2个类:Dog和CleverDog:
/* file Dog.java */
public static class Dog extends Animal {
private String name;
public Dog(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
/* file CleverDog.java */
public class CleverDog extends Dog {
public CleverDog(String name) {
super(name);
}
public void rollover() {
System.out.println(super.getName()+" rolls over!");
}
public void speak() {
System.out.println(super.getName() + " speaks!");
}
}
Run Code Online (Sandbox Code Playgroud)
现在,想象一下你是这个项目的新开发者,你需要一些聪明的狗在电视上的特定行为:那条狗必须做所有的技巧,但应该通过它的虚构电视名称.要完成此操作,请覆盖getName(...)方法...
/* file DogOnTv.java */
public class DogOnTv extends CleverDog {
String fictionalName;
public DogOnTv(String realName, String fictionalName) {
super(realName);
fictionalName = fictionalName;
}
public String getName() {
return fictionalName;
}
}
Run Code Online (Sandbox Code Playgroud)
...并陷入由原始开发人员设置的陷阱以及他们对super关键字的不寻常使用!
上面的代码不起作用 - 因为在原始CleverDog实现中,getName()使用super关键字调用.这意味着它总是调用Dog.getName()- 与任何重写无关.因此,当您使用新DogOnTv类型时......
System.out.println("Showcasing the Clever Dog!");
CleverDog showDog = new CleverDog("TugBoat");
showDog.rollover();
showDog.speak();
System.out.println("And now the Dog on TV!");
DogOnTv dogOnTv = new DogOnTv("Pal", "Lassie");
dogOnTv.rollover();
Run Code Online (Sandbox Code Playgroud)
...你得到错误的输出:
Showcasing the Clever Dog!
Tugboat rolls over!
Tugboat speaks!
And now the Dog on TV!
Pal rolls over!
Pal speaks!
Run Code Online (Sandbox Code Playgroud)
当您覆盖方法时,这不是通常的预期行为,因此您应该避免使用super不属于它的关键字来创建这种混淆.
但是,如果这实际上是您想要的行为,请使用final关键字 - 清楚地表明该方法无法被覆盖:
/* file CleverDog.java */
public class CleverDog extends Dog {
public CleverDog(String name) {
super(name);
}
public final String getName() { // final so it can't be overridden
return super.getName();
}
public void rollover() {
System.out.println(this.getName()+" rolls over!"); // no `super` keyword
}
public void speak() {
System.out.println(this.getName() + " speaks!"); // no `super` keyword
}
}
Run Code Online (Sandbox Code Playgroud)