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
^
Run Code Online (Sandbox Code Playgroud)
类B将self类型设置为class A,因此class B(或它的子类)必须扩展类A以创建实例B.但这有可能,因为一个子类B只能扩展一个类(这是类B)?
所以这引出了我的问题,在任何情况下将类的自我类型声明为另一个类是否有意义?
0__*_*0__ 10
你认为这个定义不能导致具体的实现是正确的,因为你不能混合两个类,只有特征.所以简短的回答是'不',或者应该是一个特征.
关于自我类型,Stackoverflow有几个问题.这两个有用的是:
在第二个问题中,Ben Lings给出了一个很好的答案,他引用了Spiros Tzavellas博客的以下内容:
总之,如果我们想在特征中移动方法实现,那么我们冒险使用支持具体方法的实现的抽象方法来污染这些特征的接口,并且与特征的主要责任无关.这个问题的解决方案是将这些抽象方法移动到其他特征中,并使用自我类型注释和多重继承将特征组合在一起.
例如,如果A(假设它是特征而不是现在的类!)是一个记录器.您不希望B公开公开混合的日志记录API A.因此,您将使用自我类型而不是mixin.在B您的实现中,您可以调用日志API,但从外部它是不可见的.
另一方面,您可以使用以下形式的组合:
trait B {
protected def logger: A
}
Run Code Online (Sandbox Code Playgroud)
现在的区别在于
Blogger在想要使用其功能时必须参考B有权访问的子类型loggerB并且A不要在命名空间中竞争(例如,可以使用相同名称的方法而不会发生冲突)我会说自我类型是Scala的一个相当外围的特性,在许多情况下你不需要它们,并且你有这样的选项可以在没有自我类型的情况下实现几乎相同.