2016-10-04 2 views
1

Je veux une classe pour forcer c'est sous-classes pour mettre en œuvre un sous-trait à un trait et a essayé ceci:annotation auto de type non reconnu par le compilateur

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 

Avec le code ci-dessous je reçois l'erreur du compilateur suivant:

Error:(16, 16) type mismatch; 
found : CA 
required: TA 
    def ta: TA = ca 
  1. est-ce qu'un CA ne pas être un TA quand j'ai l'annotation de type auto: « ceci: TA => » ou est-ce un problème dans le compilateur?
  2. Existe-t-il de meilleures façons de mettre en œuvre cela?

Répondre

1

Le type de soi est une sorte d '"héritage privé" (bien, ce n'est pas vraiment un héritage, mais similaire), vous ne pouvez pas l'utiliser en dehors de la classe.

Vous pourriez avoir votre CA mettre en œuvre la conversion si vous devez:

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

Quant à votre question sur une « meilleure façon de mettre en œuvre cette », il est difficile de dire, parce qu'il ne sait pas du tout ce que c'est vous essayez de faire ici. Pourquoi ne pas avoir CA par exemple TA? Comme je l'ai dit, le self-type est très similaire à un "héritage privé", et on dirait que vous voulez de l'héritage, mais vous ne voulez pas qu'il soit privé. Alors ... pourquoi ne pas utiliser l'héritage?

+0

Je souhaite qu'une classe (CA) force ses sous-classes (CB et CC) à implémenter un sous-type (TB ou TC) d'un trait TA. J'ai une méthode qui retourne une CA que je veux réutiliser dans des situations où l'aspect TA de la classe est nécessaire. Si j'ai CA étendre TA, ce ne serait pas une erreur de compilation si les sous-classes n'ont pas étendu TA ou TB. Il est intéressant que le compilateur accepte: def ca: TA = if (scala.util.Random.nextBoolean) nouveau CB() sinon nouveau CC() – user6919872

+0

Oui, bien sûr, il l'accepte, car CB et CC sont des sous-classes de TA . CA ne l'est pas. Vous ne forcez pas vos sous-classes à implémenter une sous-classe de TA avec votre approche non plus. Ils pourraient encore juste étendre TA lui-même. – Dima

0

CA par lui-même ne s'étend pas TA, l'annotation automatique signifie que vous ne pouvez utiliser CA en combinaison avec TA lors de l'extension. C'est un indice pour le compilateur. En fait, si vous regardez le bytecode CA ne s'étend rien.

Les deux CB et CC ne s'étendent TA par TB et TC, c'est pourquoi

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

œuvres.