在访问非重写的超类方法时使用'super'关键字 [英] Use of 'super' keyword when accessing non-overridden superclass methods
问题描述
我想知道的是,是否应该将super关键字用于非重写的方法?
有什么区别(对于非重写的方法/非隐藏的字段)?
我把下面的例子放在一起。
public class Vehicle {
private int tyreCost;
public Vehicle(int tyreCost){
this.tyreCost = tyreCost;
}
public int getTyreCost(){
return tyreCost;
}
}
和
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;
}
}
具体来说,假设 getTyreCost ()
未被覆盖,应 getTotalTyreReplacementCost()
使用 getTyreCost()
或 super.getTyreCost()
?
我想知道是否应在所有实例中使用super,访问超类的方法(在代码中显示您正在访问超类),或者仅在重写/隐藏的方法中(因此它们脱颖而出)。
不要使用 super
关键字来引用其他方法这些不被覆盖。
让我们来看一些 使用 super
关键字。这里我们有2个类: Dog
和 CleverDog
:
/ *文件Dog.java * /
public static class Dog extends Animal {
private String name;
public Dog(String name){
this.name = name;
}
public String getName(){
return name;
}
}
/ *文件CleverDog.java * /
public class CleverDog extends Dog {
public CleverDog (String name){
super(name);
}
public void rollover(){
System.out.println(super.getName()+roll over!
}
public void speak(){
System.out.println(super.getName()+speaks!
}
}
现在,假设你是一个新的开发者在项目上,你需要一些聪明的狗在电视上的一些特定的行为:那只狗必须做所有的技巧,但应该去它的虚构的电视名称。要完成此操作,请覆盖 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;
}
}
...陷阱由原始开发人员设置,以及他们对 super
关键字的不寻常使用!
因为在原来的 CleverDog
实现中, getName()
是使用 super
关键字。这意味着它总是调用 Dog.getName()
- 与任何覆盖无关。因此,当您使用新的 DogOnTv
类型...
系统.out.println(Showcasing the Clever Dog!);
CleverDog showDog = new CleverDog(TugBoat);
showDog.rollover();
showDog.speak();
System.out.println(现在的狗在电视上!
DogOnTv dogOnTv = new DogOnTv(Pal,Lassie);
dogOnTv.rollover();
...输出错误:
展示聪明的狗!
拖船翻滚!
拖轮说话!
现在的狗在电视上!
Pal翻身!
Pal说话!
当你覆盖一个方法时,这不是通常的预期行为,所以你应该避免创建这种类型
然而,如果这实际上是你的行为,你可以使用 super
想要,请使用 final
关键字来代替 - 清楚地表明该方法无法重写:
/ *文件CleverDog.java * /
public class CleverDog extends Dog {
public CleverDog(String name){
super
}
public final String getName(){// final因此不能重写
return super.getName();
}
public void rollover(){
System.out.println(this.getName()+roll over! // no`super`关键字
}
public void speak(){
System.out.println(this.getName()+speaks! // no`super` keyword
}
}
I'm trying to get the hang of inheritance in Java and have learnt that when overriding methods (and hiding fields) in sub classes, they can still be accessed from the super class by using the 'super' keyword.
What I want to know is, should the 'super' keyword be used for non-overridden methods?
Is there any difference (for non-overridden methods / non-hidden fields)?
I've put together an example below.
public class Vehicle {
private int tyreCost;
public Vehicle(int tyreCost) {
this.tyreCost = tyreCost;
}
public int getTyreCost() {
return tyreCost;
}
}
and
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;
}
}
Specifically, given that getTyreCost()
hasn't been overridden, should getTotalTyreReplacementCost()
use getTyreCost()
, or super.getTyreCost()
?
I'm wondering whether super should be used in all instances where fields or methods of the superclass are accessed (to show in the code that you are accessing the superclass), or only in the overridden/hidden ones (so they stand out).
Don't use the super
keyword to refer to other methods which aren't overridden. It makes it confusing for other developers trying to extend your classes.
Let's look at some code which does use the super
keyword in this way. Here we have 2 classes: Dog
and 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!");
}
}
Now, imagine you are a new developer on the project, and you need some specific behavior for a clever dog who is on TV: that dog has to do all its tricks, but should go by its fictitious TV name. To accomplish this, you override the getName(...)
method...
/* 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;
}
}
... and fall into a trap set by the original developer and their unusual use of the super
keyword!
The code above isn't going to work - because in the original CleverDog
implementation, getName()
is invoked using the super
keyword. That means it always invokes Dog.getName()
- irrelevant of any overriding. Consequently, when you use your new DogOnTv
type...
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();
... you get the wrong output:
Showcasing the Clever Dog!
Tugboat rolls over!
Tugboat speaks!
And now the Dog on TV!
Pal rolls over!
Pal speaks!
This is not the usual expected behavior when you override a method, so you should avoid creating this kind of confusion using the super
keyword where it doesn't belong.
If, however, this is actually the behavior you want, use the final
keyword instead - to clearly indicate that the method can't be overridden:
/* 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
}
}
这篇关于在访问非重写的超类方法时使用'super'关键字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!