具有另一类的自我类型的一类有意义吗? [英] Does a class with a self type of another class make sense?

查看:123
本文介绍了具有另一类的自我类型的一类有意义吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

scala> class A
defined class A

scala> class B {this: A => }
defined class B

scala> new B
<console>:10: error: class B cannot be instantiated because it does not conform
to its self-type B with A
             new B
             ^

B将自身类型设置为类A,因此,类B(或其子类)必须扩展类A才能创建B的实例.但这是否有可能,因为B的子类只能扩展一个类(这是B类)?

Class B sets the self type to class A, therefore class B (or a subclass of it) has to extend class A to create an instance of B. But is this possible at all, since a subclass of B can only extend one class (and this is class B) ?

因此,这引出我一个问题,无论如何将一个类的自身类型声明为另一个类是否有意义?

So this leads me to the question, does it make sense to declare the self type of a class to another class in any case ?

推荐答案

您的观察是正确的,因为该定义不能导致具体的实现,因为您不能混合两个类,只能混合特征.因此,简短的答案是不",应该都是一个特征.

You are right with the observation that this definition can not lead to a concrete implementation, as you cannot mix two classes, only traits. So the short answer is 'no', either should be a trait.

关于自类型,Stackoverflow有几个问题.这些是两个有用的:

There are several questions on Stackoverflow regarding self-types. Two useful ones are these:

  • What is more Scala idiomatic: trait TraitA extends TraitB or trait TraitA { self: TraitB => }
  • Difference between trait inheritance and self type annotation

在第二个问题中,本灵斯给出了一个很好的答案,他引用了

In the second question, there is a good answer by Ben Lings who cites the following passage from the blog of Spiros Tzavellas:

总而言之,如果要在特质内部移动方法实现,那么我们就有可能使用支持具体方法实现且与特质的主要职责无关的抽象方法来污染那些特质的接口.解决此问题的方法是将这些抽象方法移到其他特征中,并使用自类型注释和多重继承将这些特征组合在一起.

In conclusion, if we want to move method implementations inside traits then we risk polluting the interface of those traits with abstract methods that support the implementation of the concrete methods and are unrelated with the main responsibility of the trait. A solution to this problem is to move those abstract methods in other traits and compose the traits together using self type annotations and multiple inheritance.

例如,如果A(假设它是一个特征而不是现在的类!)是记录器.您不想公开为B公开由A混入的日志记录API.因此,您将使用自类型而不是混合.在B的实现中,您可以调用日志记录API,但是从外部看不到.

For example, if A (assume it's a trait and not a class now!) is a logger. You don't want to expose for B publicly the logging API mixed in by A. Therefore you would use a self-type and not mixin. Within the implementation of B you can call into the logging API, but from the outside it is not visible.

另一方面,您可以使用以下形式的合成:

On the other hand, you could use composition in the following form:

trait B {
    protected def logger: A
}

现在的区别是

    想要使用
  • B的功能时,必须引用logger
  • >的
  • 子类型可以访问logger
  • BA在命名空间中不竞争(例如,可以使用相同名称的方法而不会发生冲突)
  • B must refer to logger when wanting to use its functionality
  • subtypes of B have access to the logger
  • B and A do not compete in namespace (e.g. could have methods of the same name without collision)

我想说,自类型是Scala的外围功能,在很多情况下您不需要它们,并且您可以使用类似的选项在没有自类型的情况下实现几乎相同的功能.

I would say that self-types are a fairly peripheral feature of Scala, you don't need them in many cases, and you have options like this to achieve almost the same without self-types.

这篇关于具有另一类的自我类型的一类有意义吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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