Scala - расширяет vs с
Я запутался. Я нашел в моем существующем проекте. В некоторых местах extends
и в некоторых местах with
. Я не могу найти другого, если бы вы мне помогли.
Ответы
Ответ 1
Если унаследовано несколько class
es или trait
, первое всегда extends
, а следующее >= 0 class
/trait
должно быть with
s.
Но помните, что вы можете наследовать только класс <= 1 (abstract), что означает, что если вам нужно наследовать родительский класс (Parent
), он всегда должен начинаться с первой формы ... extends Parent ...
, и нет более классы могут быть унаследованы производному классу.
trait T1
trait T2
class P1
class P2
class C1 extends T1
class C2 extends T1 with T2
class C3 extends T2 with T1
class C4 extends P1 with T1
/// class C5 extends T1 with P1 // invalid
/// class C6 extends P1 with P2 // invalid
with
фактически привязан к классу/признаку, который extend
ed, например, class C7 extends P1 with T1 with T2
читает class C7 extends (P1 with T1 with T2)
.
Обратите внимание, что это только с точки зрения синтаксиса , различия семантические можно отнести к следующему:
Ответ 2
В Scala вы можете наследовать от class
es (бетон или abstract
) и trait
s. Подобно тому, как вы можете распространять только один класс, но реализовать столько интерфейсов, сколько хотите в Java, вам разрешено наследовать только один class
, но столько trait
, сколько вы хотели бы.
Если вы расширяете class
, этот класс должен сразу следовать ключевому слову extends
. Любые trait
, от которых вы распространяетесь, должны следовать, разделенные ключевыми словами with
.
Если вы не расширяете класс, вы можете поместить свой первый trait
сразу после ключевого слова extends
и продолжить после этого.
Как и в Java, каждый класс является подклассом Object
, явно или нет, каждый (определяемый пользователем) класс в Scala extends AnyRef with ScalaObject
, явно или нет.
Таким образом, следующие наборы объявлений эквивалентны:
class MyClass { ... }
class MyClass extends AnyRef with ScalaObject { ... }
class MyClass extends MySuperClass { ... }
class MyClass extends MySuperClass with ScalaObject { ... }
class MyClass extends MyTrait1 with MyTrait2 { ... }
class MyClass extends AnyRef with MyTrait1 with MyTrait2 { ... }
class MyClass extends MySuperClass with MyTrait1 with MyTrait2 { ... }
Последний пример не совпадает с изменением порядка MySuperClass
, MyTrait1
и MyTrait2
. В частности, нельзя поставить черту перед классом, и порядок, в котором вы ставите черты, важен, если они оба имеют реализации для тех же методов. (В этом случае последний "выигрывает".)
Помните, что только class
es в Scala могут иметь параметры, поэтому вы сможете когда-либо добавлять параметры к типу после ключевого слова extends
, но никогда никому из типов, перечисленных после with
.
Надеюсь, что это поможет!
Ответ 3
Первое, что вы наследуете, может быть либо признаком, либо классом, используя ключевое слово extends
.
trait SomeTrait
class SomeClass
class ThisIsValid extends SomeTrait
class ThisAsWell extends SomeClass
Вы можете определить дополнительные унаследованные черты (и только черты), используя ключевое слово with
.
class AlsoThisWorks extends SomeClass with SomeTrait
Если черта наследуется от класса, вы не можете использовать ее, как в приведенном выше примере.
Что касается ключевых слов extends
и with
. Если вы хотите узнать больше о classes и traits официальная документация углубляется по этой теме.