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

时间:2015-10-18 06:55:29

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

在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);
    }
}

我不明白为什么,来自FlyingCarsuper用于引用startEngine()OperateCar接口中FlyCar的两个版本。据我了解,startEngine()没有在任何超类中定义,因此不应该被称为常驻。我也没有看到superFlyingCar

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

2 个答案:

答案 0 :(得分:7)

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

答案 1 :(得分:5)

  

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

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

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

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

如果没有默认实现,只需要一个接口方法, 然后声明没有意义,因为接口不包含实现,如下所示:

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

我也没有看到在FlyingCar中实现的super和两个接口之间存在任何关系

不确定我明白你在问什么。 super是一种在父接口中调用实现的方法。 没有super,没有其他方法可以表达这一点。