Почему я не вижу компонент companion object расширенного класса?


У меня есть абстрактный класс:

abstract class Vec2t

И расширяющийся класс:

class Vec2 : Vec2t

Vec2t имеет следующий сопутствующий объект :

companion object {

    @JvmField val length = 2
}
Но когда я набираю Vec2.length, то он помечается как неразрешенная ссылка...

Почему? Чего мне не хватает?

1 2

1 ответ:

В Котлине companion object - это просто специально помеченный object внутри вашего класса. Вы можете опустить его имя, и он получит имя по умолчанию Companion, а также вы получите удобство использования синтаксиса MyClass.myProperty вместо MyClass.Companion.myProperty для доступа к его членам. Это, однако, все еще просто вложенный object.

Представьте, как бы все работало, если бы это был обычный вложенный объект, а не компаньон:

abstract class Vec2t {

    object LengthKeeper {
        val length = 2
    }

}

class Vec2 : Vec2t()

Вы можете получить доступ к length через Vec2t.LengthKeeper.length, но, конечно, вы не можете получить доступ к нему как Vec2.LengthKeeper.length, потому что класс Vec2 не имеет вложенного объекта с именем LengthKeeper.

Помечая переменную внутри сопутствующего объекта @JvmStatic генерирует статическую переменную для length внутри Vec2t в байт-коде, но вы можете получить доступ только к ней из Java, где запись следующего фактически работает с вашим кодом:

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

Что касается решения этой задачи в Kotlin, если вам действительно нужно получить доступ к свойству базового класса через Vec2 с этим синтаксисом, вам, вероятно, придется сделать что-то вроде этого:

class Vec2 : Vec2t() {

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

}