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

oke*_*_on 6 java interface super java-8 default-method

在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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我不明白为什么,from FlyingCar,super用于指代startEngine()in OperateCarFlyCarinterfaces的两个版本.据我所知,startEngine()没有在任何超类中定义,因此不应该被称为居民.我也没有看到super和实现的两个接口之间有任何关系FlyingCar

use*_*460 7

当你有一个实现多个接口的类时,那些接口包含具有类似方法签名的方法(例如你的startEngine方法).

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

yourInterface.super.method();
Run Code Online (Sandbox Code Playgroud)

您可以查看此链接,该链接也可以解决您的问题.

所以,你也可以这样做:

public class FlyingCar implements FlyCar, OperateCar{
    public int startEngine(EncryptedKey key) {
        return FlyCar.super.startEngine(key);
    }
}
Run Code Online (Sandbox Code Playgroud)

或这个:

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

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

然而,这种特殊情况是一个例子.更有可能发生的是你会做这样的事情:

public int startEngine(EncryptedKey key) {
    // Custom implemenation...
}
Run Code Online (Sandbox Code Playgroud)

哪个也有效.但是,如果您有两个具有相同签名的方法的接口,那么您可能还应该有一个声明该方法的单个父接口,以及两个扩展它的子接口:

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
}
Run Code Online (Sandbox Code Playgroud)

  • **Reamrks:**请注意,***default***修饰符仅在Java 8及更高版本中可用. (4认同)

Sto*_*ica 5

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

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

public interface OperateCar {
    // ...
    default public int startEngine(EncryptedKey key) {
        // Implementation
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

public interface OperateCar {
    // ...
    int startEngine(EncryptedKey key);
}
Run Code Online (Sandbox Code Playgroud)

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

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

  • @okeyxyz:没有像"默认超类"这样的东西,你不清楚为什么这么认为.`InterfaceName.super`是从实现类调用非抽象接口方法的语法.而已.看起来像这样*因为Java语言设计师这么说*.这些非抽象接口方法称为`default`方法,因为它们需要将该关键字标记为非抽象.即使没有指定*和*,也要保持与以前使用`abstract`的语言版本保持兼容,因为Java语言设计师这样说. (2认同)