在访问非重写的超类方法时使用'super'关键字 [英] Use of 'super' keyword when accessing non-overridden superclass methods

查看:166
本文介绍了在访问非重写的超类方法时使用'super'关键字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图获得Java中的继承,并已经了解到,当重写方法(和隐藏字段)在子类中,仍然可以通过使用'super'关键字从超类访问。 p>

我想知道的是,是否应该将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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆