2016-10-04 86 views
1

认可我想一个类来迫使它的子类实现子性状的性状,并试图此:自助式注释不被编译器

sealed trait TA 
sealed trait TB extends TA 
sealed trait TC extends TA 

sealed trait CA { 
    this: TA => 
} 
final class CB extends CA with TB 
final class CC extends CA with TC 

def ca: CA = if (scala.util.Random.nextBoolean) new CB() 
      else new CC() 
def ta: TA = ca 

有了下面的代码,我得到以下编译器错误:

Error:(16, 16) type mismatch; 
found : CA 
required: TA 
    def ta: TA = ca 
  1. 难道一个CA不是一个TA时,我有自己类型的注释:“这样的:TA =>”或者这是在编译器故障?
  2. 有更好的方法来实现这个吗?

回答

1

自我类型是一种“私有继承”(当然,它不是真正的继承,但类似),你不能在类之外使用它。

你可以有你的CA实现转换,如果你有:

trait CA { this: TA => 
    def ta: TA = this 
} 

至于你一下,这很难说,因为目前还不清楚在所有一个“实现这个更好的方式”的问题是什么你正试图在这里做。

为什么不有CA延伸TA例如?就像我说的那样,自我类型与“私有继承”非常相似,你听起来像你想继承,但不希望它是私有的。所以...为什么不使用继承?

+0

我想要一个类(CA)来强制它的子类(CB和CC)实现特征TA的子类型(TB或TC)。我有一个方法返回一个CA,我想在需要类的TA方面的情况下重用。 如果我有CA扩展TA,如果子类不扩展TA或TB,它将不会是编译器错误。 有趣的是,编译器接受:def ca:TA = if(scala.util.Random.nextBoolean)new CB()else new CC() – user6919872

+0

当然,它接受它,因为CB和CC都是TA的子类。 CA不是。你不强迫你的子类用你的方法实现TA的一个子类。他们仍然可以延长TA本身。 – Dima

0

CA本身不延伸TA,自我标注意味着延伸时只能使用CATA的组合。这是编译器的一个暗示。事实上,如果你看字节码CA不能扩展任何东西。

两个CBCC做通过TBTC延长TA,这就是为什么

def ca: TA = if (scala.util.Random.nextBoolean) new CB() else new CC() 

作品。