Наследование от класса Java с открытым методом, принимающим защищенный класс в Kotlin

у меня такая ситуация: Есть класс Java

public class A {

    public void overrideMe(B param){
        //TODO: override me in Kotlin!
    }

    protected static class B {

    }
}

и класс Kotlin, который наследует от него и должен переопределить метод "overrideMe"

class K: A() {
    override fun overrideMe(param: B) {
        println("Wow!")
    }
}

но Котлин не допускает такого поведения.

функция "public" предоставляет свой параметр "protected (in A)" типа B

есть ли способ решить эту проблему?

P. S. Это не просто синтетический случай - я столкнулась с этой проблемой, когда я пытался реализовать пользовательскую Весна AmqpAppender и переопределить его метод postProcessMessageBeforeSend.

2 ответов


здесь нет способа решить эту проблему в Котлине, и вот почему:

разница в том, что protected на самом деле означает что-то тонко другое в Котлине, чем в Java.

protected на Котлин означает:

Котлин защищены: так же, как private (видимый внутри файла, содержащего объявление) + видимый в подклассах тоже;

protected на Java значит:

java protected: к члену можно получить доступ только в его собственном пакете (как и в package-private) и, кроме того, подклассом его класса в другом пакете.

и с этим знанием вопрос должен быть ясен,protected static class B в Котлине больше похоже на private static class B в Java. Поэтому предупреждение правильное.

на Котлин-Java Взаимодействие руководство специально указано:

protected остается protected (обратите внимание, что Java позволяет получать доступ к защищенным членам из других классов в том же пакете, а Kotlin-нет, поэтому Java-классов будут иметь более широкий доступ к коду);

вывод:

это означает, что Котлин интерпретирует Java-protected как будто это Котлин -protected ergo нет способа реализовать class K в Котлине, как есть. По крайней мере, вы должны сделать, чтобы заставить его работать, это создать C extends A (в Java), который обрабатывает весь открытый доступ B, а затем расширить этот класс в Котлин. Как в этом выпуске вызов защищенных статических методов

виновник:

основной проблемой является поведение Javas статические вложенные классы, который

взаимодействует с членами экземпляр своего внешнего класса (и других классов), как и любой другой класс верхнего уровня. по сути, статический вложенный класс поведенчески класс верхнего уровня, который был вложен в другой класс верхнего уровня для удобства упаковки.

этой удобно поведение создает проблему в первую очередь.

Примечание:

вероятно, лучший матч для Java -protected Это Kotlins internal который обеспечивает лучший уровень инкапсуляции.

внутренние Котлин: любой клиент внутри этого модуля, который видит объявляющий класс видит своих внутренних членов;


Ну, в конце концов, вывод таков: нет способа решить эту ситуацию в чистом Котлине.

Я надеюсь, что AmqpAppender.Мероприятие станет публичным в ближайшее время.

даже если Java позволяет такое поведение, отсутствие публичных аргументов в публичных методах кажется мне плохим дизайном (также для разработчиков Kotlin).