Абсолютный член не может получить доступ напрямую: Котлин

У меня есть интерфейс A с реализованным методом t ()

interface A{ fun t() : String{ return "A" } } 

И абстрактный класс B

 abstract class B : A{ override abstract fun t(): String } 

И один класс C

 open class C: A, B(){ override fun t(): String { //return super<A>.t() // getting error return super.t() //getting error here } } 

Я хочу вызвать функцию интерфейса t (), но это дает мне ошибку. Элемент abstract не может быть напрямую доступен

Если я удалю реализацию A из B, это будет работать.

может ли кто-нибудь объяснить, почему?

В kotlin нет ссылки, но выражение Invoice Expression TypeName.super. [TypeArguments] Identifier ( [ArgumentList] ) TypeName.super. [TypeArguments] Identifier ( [ArgumentList] ) в java точно описан в JLS-15.12.3 :

Примечание : здесь интерфейс представляет собой interface class / interface .

Если TypeName обозначает интерфейс , пусть T – объявление типа, непосредственно включающее вызов метода. Ошибка времени компиляции возникает, если существует метод , отличный от объявления времени компиляции, который переопределяет (§9.4.1) объявление времени компиляции из прямого суперкласса или прямого суперинтерфейса T

В случае, когда суперинтерфейс (класс B ) переопределяет метод, объявленный в интерфейсе grandparent (интерфейс A ), это правило запрещает дочернему интерфейсу «пропускать» переопределение, просто добавляя бабушку к своду прямых суперинтерфейсов. Соответствующий способ доступа к функциям дедушки и бабушки – это прямой суперинтерфейс (класс B ), и только если этот интерфейс решит выставить желаемое поведение. (В качестве альтернативы разработчик может свободно определять свой собственный дополнительный суперинтерфейс, который предоставляет желаемое поведение при вызове супер-метода.)

Поэтому, даже если t() является конкретным методом в классе B , он также не выполнялся во время компиляции, например:

 interface A { fun t() = "A" } abstract class B : A { override fun t() = "B" } class C : A, B() { // v--- error override fun t()= super<A>.t(); // v--- ok fun ok()= super<B>.t(); } 

Следуя правилу JLS-15.12.3 , вы также не можете получить доступ к интерфейсу дедушки A если вы не позволяете классу C непосредственно реализовать A , например:

 // v-- grandparent interface A is removed from class C class C : B() { // v--- can't access the grandparent interface A override fun t() = super<A>.t(); } 

Абстрактный суперинтерфейс может повторно объявить конкретный метод в своем интерфейсе grandparent к абстрактному методу. но вы должны реализовать абстрактный метод в дочернем классе, например:

 interface GrandParent { fun foo() = "bar"; } interface Parent : GrandParent { override fun foo(): String; } // v--- must implements abstract foo() method in Parent interface class Child : Parent; 

Когда class B 'называется' interface A , он должен был реализовать функцию в интерфейсе, но не сделал этого. Вместо этого он «обещал» (используя ключевое слово abstract ) оставить эту реализацию любому классу, который ее наследует, к которому согласован interface A Теперь, когда вошел class C , он «назвал» обе function B и interface A и переопределил function t() (имеет функцию как интерфейс A, так и функция B). Теперь вопрос в том, какая из function t() переопределяется? Вы не можете этого сделать, и поэтому у вас есть ваша ошибка.

Или, используя другую аналогию, class B связан с interface A Если class B заплатил interface A , то он может помочь class C решить его задолженность с interface A , например:

 interface A{ fun t():String{ return "A" } } abstract class B :A{ override fun t():String{ return "potato" } } open class C: A, B(){ override fun t(): String { return super<B>.t() } 

Но так как это не так, class C должен решить свой собственный долг с interface A как это:

 open class C: A { override fun t(): String { return super.t() } } 

Или помогите классу B оплатить его, вот так:

 open class C: B(){ override fun t(): String { return super.t() } } 

Он не может сделать так потому, что будет создавать две функции с одной и той же сигнатурой. Надеюсь, эта аналогия помогла вам понять.