Здравствуйте, Lazy Cjow Rhrr, Вы писали:
LCR>Diamond-проблему как раз трейты решают, и это решение модульное, типобезопасное и непротиворечивое (см. статью Scalable component abstractions). Соглашусь, что несколько громоздкое из-за правил линеаризации. И ограничения есть — нетривиальные конструкторы недопустимы. Впрочем, если мы хотим позволить себе конструкторы с параметрами, тогда придётся навернуть систему типов и отношений между классами.
Вот только оно неудобное. Конструкторы реально достают, к примеру.
Diamond-проблема на практике во многом надумана, она встречается раз в пятилетку. Поэтому стоит ввести какое-то поведение для неё, но не трогать самые частые случаи использования наследования — частичные mixin'ы.
LCR>А вот то что я вижу в Котлине вызывает ряд вопросов:
LCR>LCR>open class A(virtual var v : int)
LCR>open class B(v : Int) : A(v)
LCR>open class C(v : Int) : A(v)
LCR>class D(v : Int) : B(v), C(v) {
LCR> override var v : Int
LCR> get() = this<B>.v
LCR> set(value) { this<B>.v = value }
LCR>}
LCR>
LCR>1. Требуется ли всегда вручную явно указать как разрешать противоречия? (Если да, то печаль.)
Да.
LCR>2. Сколько подобъектов A содержится в D (если 2, то это грабли, и тогда эти сопли не нужны, лучше использовать композицию, если 1, то см ниже.)
LCR>3. Как будем инициализировать подобъект А если напишем
Пока неизвестно.