В вашем примере определение Companion.foo()
является расширением в качестве члена . В этом случае вы определяете расширение в том же типе A.Companion
, что и тип расширения. Это бесполезно.
В следующем примере показана концепция расширения как члена с двумя различными классами. Пример без компаньонов, потому что это не имеет значения для концепции.
class A
class B {
fun A.foo() {
println("Extension for A, only visible in B")
println("Function has two 'this' references: ${this} and ${this@B}")
}
fun bar() {
val a = A()
a.foo() // this function call is only possible in the context of `B`
}
}
fun main() {
val a = A()
a.foo() // compile error
}
Тем не менее, две функции foo()
в вашем примере имеют разные подписи внутри. Нормальная функция foo()
- это простой метод для объекта-компаньона без параметров. Функция расширения Companion.foo()
является методом для объекта-компаньона, но с дополнительным параметром для второй ссылки this
.
Чтобы инкапсулировать методы внутри компаньонов, просто поместите модификатор private
перед функцией.
Если вам нужна встроенная функция, используйте internal
и @PublishedApi
, чтобы скрыть функцию от общедоступного API.
class C {
companion object {
@PublishedApi
internal inline fun <reified T> foo() {
println("hello in A")
}
inline fun bar() {
foo<String>()
}
}
}