【问题标题】:Confused about "super" keyword in this Java example对这个 Java 示例中的“super”关键字感到困惑
【发布时间】:2016-01-16 15:57:52
【问题描述】:

在java网站的教程page的这个例子中。两个接口定义了相同的默认方法startEngine()。一个类FlyingCar 实现了这两个接口,并且由于明显的冲突必须覆盖startEngine()

public interface OperateCar {
    // ...
    default public int startEngine(EncryptedKey key) {
        // Implementation
    }
}
public interface FlyCar {
    // ...
    default public int startEngine(EncryptedKey key) {
        // Implementation
    }
}

public class FlyingCar implements OperateCar, FlyCar {
    // ...
    public int startEngine(EncryptedKey key) {
        FlyCar.super.startEngine(key);
        OperateCar.super.startEngine(key);
    }
}

我不明白为什么,从FlyingCar 开始,super 用于在OperateCarFlyCar 接口中指代startEngine() 的两个版本。据我了解,startEngine() 没有在任何超类中定义,因此不应被称为常驻类。我也看不出superFlyingCar 中实现的两个接口之间有任何关系

【问题讨论】:

  • super 本身表示超类。 FlyCar.super 是 Java 8 中的新内容,表示接口 FlyCar 中的实现。
  • 您为什么不阅读该教程而只是提取示例代码?

标签: java interface java-8 super default-method


【解决方案1】:

当您有一个实现多个接口的类,并且这些接口包含具有相似方法签名的方法时(例如您的 startEngine 方法)。

为了知道你指的是哪种方法,你这样做:

yourInterface.super.method();

您可以查看此link,它也解决了您的问题。

所以,你也可以这样做:

public class FlyingCar implements FlyCar, OperateCar{
    public int startEngine(EncryptedKey key) {
        return FlyCar.super.startEngine(key);
    }
}

或者这个:

public class FlyingCar implements FlyCar, OperateCar{
    public int startEngine(EncryptedKey key) {
        return Operate.super.startEngine(key);
    }
}

无论哪种方式,如果您只是从接口调用方法,则必须指定调用方法的接口。

但是,这种特殊情况只是一个例子,这是有原因的。更有可能发生的是,您将执行以下操作:

public int startEngine(EncryptedKey key) {
    // Custom implemenation...
}

这也是有效的。但是,如果您有两个接口的方法具有相同的签名,这也可能是您应该有一个声明该方法的父接口和扩展它的两个子接口的情况:

public interface Car {
    // ...
    default public int startEngine(EncryptedKey key) {
        // Default implementation
};
}

public interface FlyCar extends Car {
    // Methods unique to FlyCar
}

public interface OperateCar extends Car {
    // methods unique to OperateCar
}

【讨论】:

  • Reamrks: 请注意,default 修饰符仅在 Java 8 及更高版本中可用。
【解决方案2】:

据我了解,startEngine() 没有在任何超类中定义,因此不应被称为常驻类。

是的,它已被定义。这是默认实现,例如:

public interface OperateCar {
    // ...
    default public int startEngine(EncryptedKey key) {
        // Implementation
    }
}

OperateCar.super.startEngine(key) 将执行默认实现。

如果没有默认实现,只是一个接口方法, 那么该语句就没有意义了,因为接口不包含实现,如下所示:

public interface OperateCar {
    // ...
    int startEngine(EncryptedKey key);
}

我也看不出 super 和 FlyingCar 中实现的两个接口之间有任何关系

不确定我是否理解您的要求。 super 是在父接口中调用实现的一种方式。 没有super,就没有其他方式来表达这一点。

【讨论】:

  • 我知道有一个默认实现,但你的意思是它假设了一个默认类(超级),这个默认实现是基于这个类的?这样就合乎逻辑了。而且如果有默认的超类,那么我现在可以看到两个接口和super的关系了。
  • @okeyxyz:没有像“默认超类”这样的东西,不清楚你为什么这么认为。 InterfaceName.super 是从实现类调用非抽象接口方法的语法。而已。看起来像这样因为Java 语言设计者是这样说的。这些非抽象接口方法称为default 方法,因为它们需要将该关键字标记为非抽象。这是为了与之前隐含 abstract 的语言版本保持兼容,即使没有指定 并且,因为 Java 语言设计者是这样说的。
猜你喜欢
  • 2023-03-24
  • 2018-09-29
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
  • 2014-03-29
  • 2019-04-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多