Разница между абстрактным классом и признаком [дубликат]


Возможные Дубликаты:
черты Scala против абстрактных классов

в чем концептуальная разница между абстрактными классами и признаками?

4 82

4 ответа:

класс может только продлить на один суперкласс, и, таким образом, только один абстрактный класс. Если вы хотите создать несколько классов, то Scala-это использовать состав класса mixin: вы объединяете (необязательно) суперкласс, ваши собственные определения членов и один или несколько черт. Признак ограничен по сравнению с классами в том, что он не может иметь параметры конструктора (сравните справочное руководство scala).

ограничения признаки по сравнению с классами вводятся, чтобы избежать типичных проблем с множественным наследованием. Существуют более или менее сложные правила в отношении иерархии наследования; возможно, лучше избегать иерархии, где это действительно имеет значение. ;-) Насколько я понимаю, это может иметь значение только в том случае, если вы наследуете два метода с одинаковой сигнатурой / две переменные с одинаковым именем из двух разных признаков.

одним из аспектов черт является то, что они stackable. Позволяя ограниченную форму АОП (вокруг совета).

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@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@188c838
scala> yx.a
X
Y
res1: Int = 1

разрешение super отражает линеаризацию иерархии наследования.

концептуально признак является компонентом класса, а не классом сам по себе. Как таковой, он обычно не имеет конструкторов, и он не должен "стоять сам по себе".

Я предлагаю использовать абстрактный класс, когда он имеет независимое значение, и черты, когда вы просто хотите добавить функциональность в объектно-ориентированном виде. Если вы не уверены между двумя, вы можете обнаружить, что если все ваши методы вращаются вокруг одной вещи, вы, вероятно, хотите черта характера.

для примера (не зависящего от языка), если ваш сотрудник должен расширить как "Person", так и "Cloneable", сделайте Person базовым классом, а Cloneable-чертой.

по крайней мере, в Scala система признаков имеет явный способ объявления родительского приоритета в подклассе, чтобы избежать типичных проблем, связанных с множественным наследованием, т. е. конфликтов с унаследованными методами, имеющими ту же подпись.

черты сродни интерфейсам Java,но разрешены для реализации методов.