Как справиться с этой ситуацией, связанной с реализацией интерфейса с использованием дженериков? - PullRequest
0 голосов
/ 19 апреля 2019

Мне трудно реорганизовать общий код Java в Kotlin, так как он более строгий. Я не знаю, что делать в сложившейся ситуации.

Прежде всего, у меня есть interface TopicController с абстрактными методами подписки, некоторые из которых содержат параметр type: Class<T>. Здесь <T> должен реализовывать класс Message. (<T: Message>)

У меня также есть реализация TopicController, а именно TopicControllerImpl. Этот класс имеет список узлов: val nodes: MutableList<TopicNode<T>>. Также в этом случае T должен реализовывать Message.

Для достижения этой цели я пытаюсь добавить определение реализации к классу, например: TopicControllerImpl<T : Message>. Но функции в TopicController также должны иметь эту нотацию реализации, и ее нельзя извлечь из TopicControllerImpl.

Определение его наоборот, поэтому с interface TopicController<T : Message> вынуждает меня определить Message для TopicController, поэтому: class TopicControllerImpl(args) : TopicController<*One type argument expected for interface TopicController<T : Message>*>.

Для ясности: следующий код не успешно компилируется:

TopicControllerImpl

class TopicControllerImpl<T: Message>/** ?? */(*[args]*) : TopicController {
   private val nodes: MutableList<TopicNode<T>>

   override fun subscribe(topic: String, type: Class<T>, subscriber: Messenger) {
        val node = findOrCreateNode(topic, type)
        node.addListener(subscriber)
   }

   private fun findOrCreateNode(topic: String, type: Class<T>): TopicNode<T> {
        var node = findNode<T>(topic)
        if (node != null) {
            return node
        }
        // If node doesn't exist yet, create it, run it and add it to the collection
        node = TopicNode(topic, type)
        executor.execute(node, configuration)


        nodes.add(node)

        return node
    } 

    // other functions...
}

TopicController

interface TopicController<T : Message>{ /** ?? */

     fun subscribe(topic: String, type: Class<T>, subscriber: Messenger)

     // Other methods
}

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

1 Ответ

1 голос
/ 19 апреля 2019

Согласно выводу типа в kotlin, если у вашего родителя подстановочный знак в качестве представления класса, вам нужно будет предоставить его, когда вы наследуете от него в child (это то же самое) вещь в Java).

В этом случае ваш TopicController имеет тип T с Message в качестве отражения.

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

Посмотрите на пример ниже:

interface Parent<T : SomeClass> { // Parent can be an abstract class too
    // Some methods
}

затем, как только мы реализуем это для любого ребенка,

class Child<T: SomeClass> : Parent<T> // We'll need to define T here for parent as it's unknown while inheriting
{
    // Some overridden methods
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...