Смущен "супер" ключевым словом в этом примере Java
В этом примере на странице учебника 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
, super
используется для обозначения обеих версий startEngine()
в OperateCar
а также FlyCar
интерфейсы. Как я понимаю, startEngine()
не был определен ни в одном суперклассе, поэтому не должен называться резидентным в одном. Я также не вижу никакой связи между super
и два интерфейса, как реализовано в FlyingCar
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
Нет другого способа выразить это.
Если у вас есть класс, реализующий несколько интерфейсов, и эти интерфейсы содержат методы с похожей сигнатурой метода (например, для вашего метода 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
}