【问题标题】:When should I use a regular class in Scala?我什么时候应该在 Scala 中使用常规课程?
【发布时间】:2016-09-13 17:55:08
【问题描述】:

在我看来,我可以使用objecttraitabstract class 以及在极少数情况下使用case class 来制作任何东西。其中大部分是object extends trait 的形式。所以,我想知道,如果有的话,我什么时候应该使用简单的标准class

【问题讨论】:

  • Martin Odersky 实际上说过 Scala 只需要方法、类型成员、类型投影、路径、对象和特征。其他一切基本上只是为了平台互操作性。然而,由于其他的一切都那里,有些东西比其他东西更有意义。 IOW,尽管类和特征确实重叠,但两者都有不同的用例。

标签: scala class oop inheritance


【解决方案1】:

这里不适合问这个问题

看来你是新人Scala

Class 是您要建模的某物(某些实体)的规范。它包含行为和状态

只有一种方法可以使用关键字class声明所谓的常规类

traitabstract class 都用于继承。

trait 用于继承(通常将常见的行为放在那里)。 trait 类似于 Java 中的接口。多重继承可能与特征但不是abstract class

一个类可以扩展一个类或抽象类,但可以混合任意数量的特征。特征可以有行为和状态。

case class 只不过是一个类,但编译器会为我们生成一些样板代码,以使事情变得简单且美观。

object 用于当您想要声明某个类但您希望在 JVM 中拥有该类的单个实例时(请记住单例模式)。

【讨论】:

  • 为什么这里不适合问这个问题?
  • @AlvaroCarrasco 这个问题需要解释基本概念。答案可以尽可能长(主观),没有任何限制。 Stackoverflow 更适用于您已经尝试过并需要帮助的代码相关问题。还有其他关于主观概念相关问题的论坛。阅读 stackoverflow 提问规则。
【解决方案2】:

如果一个对象对其成员执行有状态计算,即它的成员用 vars 声明;

或者,即使它的成员只用 vals 声明,但那些 vals 存储可以就地编辑的可变数据结构,那么它应该是一个类似于 Java 可变对象的普通(可变)类。

在 Scala 中使用 Case 类的惯用方式是不可变类型,即所有构造函数参数都是 val。我们可以使用 vars,但这样就失去了 case 类的优势,比如相等比较会随着时间的推移而中断。

Odersky 等人的 Programming in Scala 提出了一些关于在使用特征、抽象类和具体类之间做出决定的建议:

如果该行为不会被重用,则将其设为具体类。毕竟这不是可重用的行为。

如果它可以在多个不相关的类中重用,请将其设为 trait。 只有特质可以混合到类层次结构的不同部分中。

如果您想在 Java 代码中继承它,请使用抽象类。 由于带有代码的特征没有与 Java 相似的类似物,因此它往往是 从 Java 类中继承特征很尴尬。继承自 同时,Scala 类与从 Java 类继承完全一样。 作为一个例外,只有抽象成员的 Scala 特征可以翻译 直接连接到 Java 接口,所以你应该随意定义这样的 即使您希望 Java 代码从它继承,也可以使用特征。见第 29 章 了解有关一起使用 Java 和 Scala 的更多信息。

如果您打算以编译的形式分发它,并且您希望在外部 组来编写继承自它的类,您可能倾向于 使用抽象类。问题是当一个特征获得或失去时 一个成员,任何继承自它的类都必须重新编译,即使 他们没有改变。如果外部客户只会调用 行为,而不是从它继承,然后使用特征就可以了。

如果效率非常重要,请倾向于使用类。大多数Java 运行时使类成员的虚拟方法调用更快 操作比接口方法调用。特征被编译为 接口,因此可能会支付轻微的性能开销。 但是,只有当您知道该特征时,您才应该做出此选择 有问题构成性能瓶颈并有证据 使用类实际上可以解决问题。

如果你还是不知道,在考虑了以上之后,那就从 使它成为一种特征。你总是可以 稍后更改它,通常使用 trait 会保留更多选项。

【讨论】:

    猜你喜欢
    • 2015-05-19
    • 2011-01-25
    • 2023-04-10
    • 1970-01-01
    • 2011-10-06
    • 1970-01-01
    • 2010-12-30
    相关资源
    最近更新 更多