Ковариантный тип возврата и объявление throws
В этой иерархии ниже,
Ниже приведен скомпилированный код для этого вопроса:
class T3 {}
class T2 extends T3{}
class T1 extends T2{}
class T5 extends T1{}
class E3 extends Throwable {}
class E2 extends E3 {}
class E1 extends E2 {}
class E5 extends E1 {}
interface I1{
T1 m() throws E1;
}
interface I2{
T2 m() throws E2;
}
interface I3{
T3 m() throws E3;
}
interface I4 extends I1, I2, I3{
}
interface I5 extends I1, I2, I3{
T5 m() throws E5;
}
В приведенном выше коде, interface I4
а также interface I5
быть скомпилированным, потому что,
1)
interface I4 extends I1, I2, I3
только когда,
T1 extends T2
& T1 extends T3
& T2 extends T3
а также
E1 extends E2
& E1 extends E3
& E2 extends E3
,
2)
interface I5 extends I1, I2, I3
и переопределяет m()
как T5 m() throws E5;
только когда,
T5 extends T1
& T5 extends T2
& T5 extends T3
а также
E5 extends E1
& E5 extends E2
& E5 extends E3
,
Что касается ковариантного типа возвращаемых значений и объявления типа throws,
Можно ли сказать, что код успешно скомпилирован, потому что два вышеуказанных правила являются действительными и необходимыми?
2 ответа
Код компилируется, потому что Java допускает ковариантный тип возвращаемого значения:
Этот метод, называемый ковариантным типом возврата, означает, что тип возвращаемого значения может изменяться в том же направлении, что и подкласс.
Принцип подстановки Лискова: понятие Лискова поведенческого подтипа определяет понятие подстановочности для объектов; то есть, если S является подтипом T, то объекты типа T в программе могут быть заменены объектами типа S без изменения каких-либо желательных свойств этой программы.
Вот UML-диаграммы вашего кода:
I4
интерфейс имеет 3 метода m()
но их тип возврата отличается. I5
интерфейс имеет 4 метода m()
и их тип возврата также отличается.
Да, вы можете сказать, что код скомпилирован правильно, потому что эти правила действительны и необходимы.
Если T5 не расширяет T1, T2 и T3, то I4 и I5 не будут компилироваться.
Если E5 не расширяет E1, E2 и E3, то I5 не будет компилироваться (I4 продолжит компиляцию, потому что теоретически разработчик I4 может создать свой собственный класс исключений, который расширяет E1, E2 и E3).