In Kotlin, if I have a function in a companion object with Companion.
as the prefix (Companion.foo
), what difference will it make compared to a foo
inside the companion object?
I noticed that in the following code, Companion.foo
will make it invisible to the outside scope, but still visible to functions inside the same companion object.
You can find the code snippet at: https://pl.kotl.in/t6FvM6ni6
fun main() {
A.foo() // compiler complains "unresolved reference"
A.bar()
B.foo()
}
class A {
companion object {
fun Companion.foo() {
println("hello in A")
}
fun bar() {
foo()
}
}
}
class B {
companion object {
fun foo() {
println("hello in B")
}
}
}
Are there any other differences? Are A.Companion.foo
and A.foo
the same apart from the visibility? Is this a way to encapsulate methods in the companion object?
Update 1
In my actual project, I'm calling an inline
function from another inline
function in the companion object, which is why access modifiers can't be used. But I still would like to hide foo
if possible.
class C {
companion object {
inline fun <reified T> Companion.foo() {
println("hello in A")
}
inline fun bar() {
foo<String>()
}
}
}
In your example, the definition
Companion.foo()
is an extension as a member. In this case you define the extension in the same typeA.Companion
as the type of the extension. This is not useful.The next example shows the concept of an extension as member with two different classes. The example is without companions, because it makes no difference for the concept.
That all said, the two
foo()
function in your example have different signatures internally. The normal functionfoo()
is a simple method on the companion object without parameters. The extension functionCompanion.foo()
is a method on the companion object but with an extra parameter for the secondthis
reference.To encapsulate methods within companions, just put the
private
modifier before the function.If you need an inline function, use
internal
and@PublishedApi
to hide the function from the public API.