Scala - 扩展 vs with

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41031166/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 08:54:46  来源:igfitidea点击:

Scala - extends vs with

scalaextends

提问by Sri Manga

I am confused. In my existing project, I am not able to find the difference between extendsand with. Could you please help me?

我很迷惑。在我现有的项目,我无法找到之间的差异extendswith。请你帮助我好吗?

回答by Hongxu Chen

If you have multiple classes or traits to inherit, the first one is always extends, and the following >=0 class/traitto be withs.

如果有多个classes或traits要继承,第一个总是extends,后面的>=0 class/traitwiths。

But remember that you can only inherit<=1 (abstract) class, which means if you need to inherit a parent class (Parent), it should always comes at first of the form ... extends Parent ..., and no more classes can be inherited to the derived class.

但是请记住,您只能继承<=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

withis in fact bound to the class/trait that is extended, e.g., class C7 extends P1 with T1 with T2reads class C7 extends (P1 with T1 with T2).

with实际上绑定到被extend编辑的类/特征,例如,class C7 extends P1 with T1 with T2读取class C7 extends (P1 with T1 with T2)

Note that this is only from the viewpoint of syntax, the semanticdifferences can be referred from the followings:

请注意,这只是从语法的角度来看,语义差异可以参考以下内容:

  1. use of traitand (abstract) classis here;
  2. The resolution rule is the so-called class linearization; there is a post about it.
  1. 使用trait和(abstractclass在这里;
  2. 解析规则就是所谓的 类线性化;有一篇关于它的帖子

回答by Todd O'Bryan

In Scala, you can inherit from classes (concrete or abstract) and traits. In a similar way to how you can extend only one class, but implement as many interfaces as you'd like in Java, you're only allowed to inherit from one class, but as many traits as you'd like.

在 Scala 中,您可以从classes(具体或abstract)和traits继承。与如何仅扩展一个类但在 Java 中实现任意数量的接口的方式类似,您只能从一个继承class,但可以继承任意数量的traits。

If you are extending a class, that class should immediately follow the extendskeyword. Any traits you are extending from should follow, separated by withkeywords.

如果您要扩展 a class,则该类应紧跟在extends关键字之后。trait您要扩展的任何s 都应该跟在后面,用with关键字分隔。

If you are not extending a class, you can put your first traitright after the extendskeyword and continue after that.

如果不扩展一个类,你可以把你的第一个trait后右侧extends的关键字,之后继续。

Just as in Java, every class is a subclass of Objectwhether you explicitly declare it or not, every (user-defined) class in Scala extends AnyRef with ScalaObjectwhether or not you include that explicitly.

就像在 Java 中一样,每个类都是Object您是否显式声明它的子类,Scala 中的每个(用户定义的)类extends AnyRef with ScalaObject无论您是否显式包含它。

The following sets of declarations are therefore equivalent:

因此,以下几组声明是等效的:

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 { ... }

The last example is not the same if you change the order of MySuperClass, MyTrait1, and MyTrait2. In particular, you cannot put a trait in front of a class and the order in which you stack traits is important if they both have implementations for the same methods. (In that case, the last one "wins".)

最后一个例子是不一样的,如果你改变的顺序MySuperClassMyTrait1MyTrait2。特别是,您不能将 trait 放在类的前面,如果它们都有相同方法的实现,则堆叠 trait 的顺序很重要。(在这种情况下,最后一个“获胜”。)

Remember also that only classes in Scala can have parameters, so you'll only ever be able to attach parameters to the type after the extendskeyword, never to any of the types listed after with.

还要记住class,Scala中只有es 可以有参数,因此您只能将参数附加到extends关键字之后的类型,而不能附加到 之后列出的任何类型with

Hope that helps!

希望有帮助!

回答by stefanobaghino

The first thing you inherit from can either be a trait or a class, using the extendskeyword.

您继承的第一件事可以是特征或类,使用extends关键字。

trait SomeTrait
class SomeClass

class ThisIsValid extends SomeTrait
class ThisAsWell extends SomeClass

You can define further inherited traits (and only traits) using the withkeyword.

您可以使用with关键字定义进一步继承的特征(并且仅特征)。

class AlsoThisWorks extends SomeClass with SomeTrait

If a trait inherits from a class you cannot use it like in the above example.

如果一个 trait 继承自一个类,你就不能像上面的例子那样使用它。

That's it regarding the extendsand withkeywords. If you want to learn more about classesand traitsthe official documentation goes in depth on the topic.

这就是关于extendswith关键字。如果您想了解有关特征的更多信息,官方文档将深入讨论该主题。