微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java – 访问非重写的超类方法时使用’super’关键字

我试图在 Java中获得继承权,并且已经了解到当在子类中重写方法(和隐藏字段)时,仍然可以使用“super”关键字从超类中访问它们.

我想知道的是,’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关键字来引用其他未被覆盖的方法.这使得其他试图扩展您的类的开发人员感到困惑.

让我们看看一些以这种方式使用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!");
    }

}

现在,想象一下你是这个项目的新开发者,你需要一些聪明的狗在电视上的特定行为:那条狗必须做所有的技巧,但应该通过它的虚构电视名称.要完成此操作,请覆盖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;
    }

}

…并陷入由原始开发人员设置的陷阱以及他们对超级关键字的不寻常使用!

上面的代码不起作用 – 因为在原始的CLeverDog实现中,使用super关键字调用getName().这意味着它总是调用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();

…你得到错误输出

Showcasing the CLever Dog!
Tugboat rolls over!
Tugboat speaks!

And Now the Dog on TV!
Pal rolls over!
Pal speaks!

当您覆盖方法时,这不是通常的预期行为,因此您应该避免使用不属于它的超级关键字来创建这种混淆.

但是,如果这实际上是您想要的行为,请使用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
    }

}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


应用场景 C端用户提交工单、工单创建完成之后、会发布一条工单创建完成的消息事件(异步消息)、MQ消费者收到消息之后、会通知各处理器处理该消息、各处理器处理完后都会发布一条将该工单写入搜索引擎的消息、最终该工单出现在搜索引擎、被工单处理人检索和处理。 事故异常体现 1、异常体现 从工单的流转记录发现、
线程类,设置有一个公共资源 package cn.org.chris.concurrent; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * @Descrip
Java中的数字(带有0前缀和字符串)
在Java 9中使用JLink的目的是什么?
Java Stream API Filter(过滤器)
在Java中找到正数和负数数组元素的数量
Java 9中JShell中的不同启动脚本是什么?
使用Java的位填充错误检测技术
java中string是什么
如何使用Java中的JSON-lib API将Map转换为JSON对象?