对这个 Java 示例中的 "super" 关键字感到困惑

Confused about "super" keyword in this Java example

此示例位于 java 网站的教程 page 上。两个接口定义了相同的默认方法startEngine()。 class 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开始,superOperateCarFlyCar接口中都用来指代startEngine()的两个版本.据我了解,startEngine() 没有在任何超级 class 中定义,因此不应被称为常驻。我也没有看到 superFlyingCar

中实现的两个接口之间有任何关系

As I understand it, startEngine() was not defined in any super class, therefore shouldn't be referred as resident in one.

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

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

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

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

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

I also do not see any relationship between super and the two interfaces as implemented in FlyingCar

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

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

为了知道您指的是哪种方法,您可以:

yourInterface.super.method();

你可以看看这个,它也解决了你的问题。

所以,你也可以这样做:

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
}