Search code examples
kotlincompanion-object

Why I don't see companion object component of extended class?


I have an abstract class:

abstract class Vec2t

and an extending class:

class Vec2 : Vec2t

Vec2t has the following companion object:

companion object {

    @JvmField val length = 2
}

But when I type Vec2.length, then it's marked as unresolved reference...

Why? What am I missing?


Solution

  • In Kotlin, a companion object is just a specially marked object inside your class. You can omit its name, and it will get the default name of Companion, and you also get the convenience of being able to use the MyClass.myProperty syntax instead of MyClass.Companion.myProperty to access its members. It is, however, still just a nested object.

    Imagine how things would work if it was a regular nested object instead of a companion:

    abstract class Vec2t {
    
        object LengthKeeper {
            val length = 2
        }
    
    }
    
    class Vec2 : Vec2t()
    

    You could access the length via Vec2t.LengthKeeper.length, but of course you couldn't access it as Vec2.LengthKeeper.length, because the Vec2 class does not have a nested object called LengthKeeper.

    Marking a variable inside the companion object @JvmStatic does generate a static variable for length inside Vec2t in the bytecode, but you can only access that from Java, where writing the following does in fact work with your code:

    Vec2 v = new Vec2();
    int length = Vec2.getLength();
    

    As for solving this in Kotlin, if you really have to access the property of the base class through Vec2 with that syntax, you'll probably have to do something like this:

    class Vec2 : Vec2t() {
    
        companion object {
            val length get() = Vec2t.length
        }
    
    }