使用Traits的Scala客户端组合与实现抽象类的比较 [英] Scala client composition with Traits vs implementing an abstract class

查看:90
本文介绍了使用Traits的Scala客户端组合与实现抽象类的比较的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经读过Scala,通常建议使用Traits而不是Abstract类来扩展基类。

I have read that with Scala, it is generally advised to use Traits instead of Abstract classes to extend a base class.

下面是一个很好的设计模式,布局?

Is the following a good design pattern and layout? Is this how Traits were intended to replace Abstract?


  • 客户端类(具有def function1)

  • trait1类(覆盖function1)

  • trait2类(覆盖function1)

  • specificClient1用trait1扩展客户端

  • specificClient2使用trait2扩展客户端

  • client class (with def function1)
  • trait1 class (overrides function1)
  • trait2 class (overrides function1)
  • specificClient1 extends client with trait1
  • specificClient2 extends client with trait2

推荐答案

我不知道您的索赔来源您应该在Scala中使用特征而不是抽象类,但是 not 有以下几个原因:

I don't know what your source is for the claim that you should prefer traits over abstract classes in Scala, but there are several reasons not to:


  1. 特质复杂Java兼容性。如果您具有伴随对象的特征,则从Java调用伴随对象上的方法需要使用奇怪的 MyType $ .MODULE $ .myMethod 语法。带有伴随对象的抽象类不是这种情况,它们在JVM上作为具有静态和实例方法的单个类实现。用Java中的具体方法实现Scala特性更加令人讨厌。

  2. 将具有实现的方法添加到特性中以不向类添加具体方法的方式破坏二进制兼容性

  3. 特质会导致更多的字节码和与使用c#相关的额外开销

  4. 特质更为强大,这很糟糕—通常,您要使用功能最弱的抽象来完成工作。如果您不需要它们支持的多种继承(很多时候不需要),最好不要访问它。

  1. Traits complicate Java compatibility. If you have a trait with a companion object, calling methods on the companion object from Java requires bizarre MyType$.MODULE$.myMethod syntax. This isn't the case for abstract classes with companion objects, which are implemented on the JVM as a single class with static and instance methods. Implementing a Scala trait with concrete methods in Java is even more unpleasant.
  2. Adding a method with an implementation to a trait breaks binary compatibility in a way that adding concrete methods to a class doesn't.
  3. Traits result in more bytecode and some additional overhead related to the use of forwarder methods.
  4. Traits are more powerful, which is bad—in general you want to use the least powerful abstraction that gets the job done. If you don't need the kind of multiple inheritance they support (and very often you don't), it's better not to have access to it.

在我看来,最后一个原因是最重要的。在以后的Scala版本中,至少有两个其他问题可能会得到解决,但默认情况下,类仍然会以(至少可以说)与良好设计保持一致的方式约束程序。如果您确定自己确实确实想要特质提供的功能,它们仍然存在,但这将是您做出的决定,而不是您只是陷入的事情。

The last reason is by far the most important in my view. At least a couple of the other issues might get fixed in future versions of Scala, but it will remain the case that defaulting to classes will constrain your programs in ways that are (at least arguably) consistent with good design. If you decide you actually really do want the power provided by traits, they'll still be there, but that'll be a decision you make, not something you just slip into.

因此,不,在没有其他信息的情况下,我建议使用一个抽象类(最好是一个密封的类)和两个提供实现的具体类。

So no, in the absence of other information, I'd suggest using an abstract class (ideally a sealed one) and two concrete classes that provide implementations.

这篇关于使用Traits的Scala客户端组合与实现抽象类的比较的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆