Разница между абстрактным классом и чертой

Возможный дубликат:
Черты 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, но им разрешено иметь реализации методов.

Другие вопросы по тегам