Разница между абстрактным классом и чертой
Возможный дубликат:
Scala черты против абстрактных классов
Какова концептуальная разница между абстрактными классами и чертами?
Ответы
Ответ 1
Класс может только расширить один суперкласс и, следовательно, только один абстрактный класс. Если вы хотите составить несколько классов, способ Scala состоит в использовании состава класса mixin: вы объединяете (необязательный) суперкласс, свои собственные определения членов и один или несколько признаков . Характеристика ограничена по сравнению с классами тем, что она не может иметь параметры конструктора (сравните справочное руководство scala).
Ограничения признаков по сравнению с классами вводятся, чтобы избежать типичных проблем с множественным наследованием. Существуют более или менее сложные правила в отношении иерархии наследования; было бы лучше избегать иерархии, где это действительно имеет значение.;-) Насколько я понимаю, это может иметь значение только в том случае, если вы наследуете два метода с одной и той же сигнатурой/двумя переменными с тем же именем из двух разных признаков.
Ответ 2
Один из аспектов заключается в том, что они стекируются. Разрешить ограниченную форму AOP (вокруг совета).
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 = [email protected]
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 = [email protected]
scala> yx.a
X
Y
res1: Int = 1
Разрешение super
отражает линеаризацию иерархии наследования.
Ответ 3
Концептуально черта является компонентом класса, а не классом. Как таковой, у него обычно нет конструкторов, и он не предназначен для "стоять сам по себе".
Я предлагаю использовать абстрактный класс, когда он имеет независимое значение, и черты, когда вы просто хотите добавить функциональность объектно-ориентированным способом. Если вы не уверены между двумя, вы можете обнаружить, что, если все ваши методы вращаются вокруг одной вещи, вам, вероятно, нужна черта.
Для примера (неязыкового), если ваш сотрудник должен расширять как "Person", так и "Cloneable", сделайте Person базовым классом и Cloneable a trait.
Ответ 4
По крайней мере, в Scala система признаков имеет явный способ объявления родительского приоритета в подклассе, чтобы избежать типичных проблем, связанных с множественным наследованием, то есть конфликты с унаследованными методами, имеющими одну и ту же подпись.
Черты сходны с интерфейсами Java, но им разрешено иметь реализации методов.