Разница между абстрактным классом и чертой
Возможный дубликат:
Черты Scala против абстрактных классов
В чем концептуальная разница между абстрактными классами и чертами?
4 ответа
Класс может расширять только один суперкласс и, следовательно, только один абстрактный класс. Если вы хотите создать несколько классов, то в Scala можно использовать сочетание классов mixin: вы объединяете (необязательный) суперкласс, ваши собственные определения членов и одну или несколько характеристик. По сравнению с классами черта ограничена тем, что она не может иметь параметров конструктора (сравните справочное руководство по scala).
Ограничения признаков по сравнению с классами введены, чтобы избежать типичных проблем с множественным наследованием. Существуют более или менее сложные правила в отношении иерархии наследования; было бы лучше избегать иерархии, где это на самом деле имеет значение.;-) Насколько я понимаю, это может иметь значение только в том случае, если вы наследуете два метода с одинаковой сигнатурой / двумя переменными с одинаковым именем от двух разных признаков.
Одним из аспектов черт является то, что они являются наращиваемыми. Разрешение ограниченной формы АОП (вокруг совета).
trait A{
def a = 1
}
trait X extends A{
override def a = {
println("X")
super.a
}
}
trait Y extends A{
override def a = {
println("Y")
super.a
}
}
scala> val xy = new AnyRef with X with Y
xy: java.lang.Object with X with Y = $anon$1@6e9b6a
scala> xy.a
Y
X
res0: Int = 1
scala> val yx = new AnyRef with Y with X
yx: java.lang.Object with Y with X = $anon$1@188c838
scala> yx.a
X
Y
res1: Int = 1
Разрешение super
отражает линеаризацию иерархии наследования.
Концептуально, черта - это компонент класса, а не сам класс. Как таковой, он, как правило, не имеет конструкторов, и он не предназначен для "самостоятельности".
Я предлагаю использовать абстрактный класс, когда он имеет независимое значение, и черты, когда вы просто хотите добавить функциональность объектно-ориентированным способом. Если вы не уверены между ними, вы можете обнаружить, что если все ваши методы вращаются вокруг одной и той же вещи, вам, вероятно, нужна черта.
Для примера (не зависящего от языка), если ваш Сотрудник должен расширить и "Person" и "Cloneable", сделайте Person базовым классом, а Cloneable - чертой.
По крайней мере в Scala система признаков имеет явный способ объявления родительского приоритета в подклассе, чтобы избежать типичных проблем, связанных с множественным наследованием, то есть конфликтов с унаследованными методами, имеющими одну и ту же сигнатуру.
Черты похожи на интерфейсы Java, но им разрешено иметь реализации методов.