Итак, у меня есть абстрактный класс Composition, у которого есть два потомка: один - это трек, а другой - альбом (который является группой треков).
class Composition(val name: String, ...)
class Track(name: String): Composition(name)
class Album(name: String, val tracks: List<Track>): Composition(name)
Пока все хорошо. Теперь у меня есть продолжительность, которая добавлена. Он абстрактен в композиции, поэтому я могу переопределить его у детей:
abstract class Composition(...){
abstract fun getDuration(): Int
}
Теперь я могу добавить метод переопределения в дорожке, который принимает его в качестве параметра:
class Track(..., private val duration: Int): Composition(...){
override fun getDuration() = duration
}
И, наконец, я делаю альбом, длительность которого равна сумме треков:
class Album(..., val tracks: List<Track>): Composition(...){
override fun getDuration() = tracks.sumBy { it.getDuration() }
}
Он работает как задумано, но я не понимаю, почему я не могу просто использовать tracks.sumBy { it.duration }
, поскольку в свойствах Kotlin есть не что иное, как геттеры и сеттеры (я имею в виду getDuration
в Composition
).
Мне кажется, что я что-то упускаю, потому что, если бы тот же код был написан на Java, я мог бы назвать composition.duration
как свойство - так что я думаю, что Kotlin позволяет это делать из кода Java, но не из кода Котлина, что печально.
Другой пример:
Допустим, у меня есть класс с именем Artist
, который написал несколько Composition
s:
class Artist(
val nom: String,
private val _compositions: MutableList<Composition> = ArrayList()
) {
// HERE (I wrote the extension method List<E>.toImmutableList)
fun getCompositions() : List<Composition> = _compositions.toImmutableList()
}
Это стандарт в Java (предоставление неизменяемых версий коллекций через геттеры, поэтому они не модифицируются); Котлин не признает это, хотя:
val artist = Artist("Mozart")
artist.getCompositions() // Legal
artist.compositions // Illegal
Я думал о том, чтобы сделать это собственностью, но:
- Если я выберу тип List<E>
, я могу переопределить метод получения для возврата неизменяемого списка, но я не могу использовать обычные методы (add
...), поскольку List
является неизменным
- Если я выберу тип MutableList<E>
, я не смогу переопределить метод get для возврата ImmutableList
(который является подклассом List
, который я написал, и, очевидно, не является подклассом MutableList
).
Есть вероятность, что я делаю что-то нелепое, хотя есть простое решение, но сейчас я не могу его найти.
В конце мой вопрос таков: почему написанные вручную геттеры не считаются свойствами при написании из Kotlin?
И, если я ошибаюсь, каков ожидаемый способ решения обоих этих шаблонов?