Котлин. Как реализовать внутренний интерфейс в открытом классе?

#kotlin

#kotlin

Вопрос:

Я хочу, чтобы открытый класс реализовывал внутренний интерфейс и использовал этот интерфейс только внутри пакета. Если я сделаю этот внутренний интерфейс не внутренним, это потребует от меня сделать не внутренними все классы, используемые в этом интерфейсе, а затем создаст домино изменений, поэтому мне нужно сделать все не внутренним

что-то вроде:

 open class Form : Interface {
  override fun a(): ActionExecutor {}
}

internal interface Interface {
  fun a(): ActionExecutor
}
  

Когда я пытаюсь его скомпилировать, я получаю следующую ошибку
Form.kt: (74, 16): 'public' function exposes its 'internal' return type ActionExecutor

Комментарии:

1. Есть ли какие-либо ошибки при попытке реализовать внутренний интерфейс?

2. Да, добавлено в описание

3. Это ActionExecutor класс bcz является внутренним. Можете ли вы сделать его не внутренним?

Ответ №1:

Когда интерфейс помечен internal модификатором, любой клиент внутри этого модуля, который видит объявляющий класс, видит его внутренние члены. Если вы хотите использовать объект с internal модификатором в другом модуле, вы должны удалить этот модификатор. Это может привести к удалению цепочки, поскольку эта сущность может использовать другие internal сущности.

Когда вы реализуете internal интерфейс с использованием public класса, вы предоставляете доступ к его internal членам, что запрещено.

Ответ №2:

Когда я пытаюсь его скомпилировать, я получаю следующую форму ошибки.kt: (74, 16): «общедоступная» функция предоставляет свой «внутренний» возвращаемый тип ActionExecutor

Тогда fun a(): ActionExecutor уже не может быть общедоступным Form , независимо от реализации Interface . Потому что, если бы это было так, пользователи вне модуля могли бы вызвать его и получить an ActionExecutor , чего они не должны быть в состоянии.

Один из вариантов — не реализовывать интерфейс напрямую Form , а создать метод / свойство, возвращающее его:

 open class Form {
    // some methods
    internal val asInterface: Interface = object : Interface {
        override fun a(): ActionExecutor {
            // can access members of Form here
        }
    }
}
  

Тогда код в том же модуле может свободно видеть a Form как an Interface , а внешний код не может, так что проблем нет.