我很困惑。在我的现有项目中,我无法找到extends
和with
之间的区别。请问您能帮我吗?
如果你有多个要继承的class
或trait
,第一个是extends
,后面的>=0个class
/trait
需要使用with
。
但请记住,你只能继承<=1个(抽象)类,这意味着如果你需要继承一个父类(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
的类/特质,例如,class C7 extends P1 with T1 with T2
读作 class C7 extends (P1 with T1 with T2)
。
需要注意的是,这只是从语法的角度来看,语义上的区别可以从以下内容中参考:
在Scala中,您可以继承自具体的或抽象的class
和trait
。与Java中您可以扩展一个类,但实现任意数量的接口类似,您只能从一个class
继承,但是可以从任意数量的trait
继承。
如果您正在扩展一个class
,该class
应紧跟在extends
关键字之后。您要扩展的任何trait
应跟在其后,用with
关键字隔开。
如果您不扩展任何class
,则可以将第一个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
的顺序,那么最后一个例子就不一样了。特别地,你不能把trait放在类前面,并且如果它们都对同一个方法有实现,那么组合trait的顺序很重要(在这种情况下,以最后一个为准)。
请记住,只有Scala中的class
可以有参数,因此您只能将参数附加到extends
关键字之后的类型,而不能将其附加到with
之后列出的任何类型。
希望这可以帮到你!
你从中继承的第一件事可以是特征或类,使用extends
关键字。
trait SomeTrait
class SomeClass
class ThisIsValid extends SomeTrait
class ThisAsWell extends SomeClass
您可以使用with
关键字定义进一步继承的特征(仅限特征)。
class AlsoThisWorks extends SomeClass with SomeTrait
如果一个特征从一个类中继承,你不能像上面的例子那样使用它。