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



本例在java网站的教程页面上。两个接口定义了相同的默认方法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开始,superOperateCarFlyCar接口中同时指代startEngine()的两个版本。据我所知,startEngine()没有在任何超类中定义,因此不应该被称为驻留在一个超类中。我也没有看到superFlyingCar

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

当你有一个实现多个接口的类,并且这些接口包含具有相似方法签名的方法(例如你的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
}

据我所知,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,就没有其他表达方式了。

最新更新