2016-02-01 1 views
1

Je lis l'exemple 5.2.2 de http://www.scala-lang.org/docu/files/ScalaReference.pdf ==>L'héritage en scala sans utiliser mot-clé extends

Exemple 5.2.2

Un langage utile pour empêcher les clients d'une classe de construire de nouvelles instances de cette catégorie consiste à déclarer la classe abstraite et scellé :

object 
    m { 
    abstract sealed class 
    C (x: Int) { 
      def nextC = new C(x + 1) {} } val= empty = new C(0) {} 
} 

Par exemple, dans le code ci-dessus Les clients peuvent créer des instances de la classe m.c que par Call- la méthode ing NEXTC d'un existant m.c objet ; il n'est pas possible pour les clients de créer objets de la classe m.C directement. En effet, les deux lignes suivantes sont à la fois dans l'erreur:

new m.C(0) **** error: C is abstract, so it cannot be instantiated. 

new m.C(0) {} ****error: illegal inheritance from sealed class. 

====

Je ne peux pas comprendre comment l'héritage est déclaré !! Merci

Répondre

1

Vous pouvez hériter d'un sealed class uniquement à partir du même fichier. Cependant, vous pouvez utiliser ce type n'importe où dans votre programme.

Il s'agit d'une tentative d'instanciation: new m.C(0), ce qui n'est pas autorisé car la classe est abstraite. Vous devez fournir une implémentation, c'est-à-dire au moins un corps de constructeur vide: {}.

Cependant, une fois que vous essayez de le faire avec new m.C(0) {} vous créez en fait une nouvelle classe anonyme qui est un sous-type de A, qui est également interdit à l'extérieur (un autre fichier), d'où l'erreur. C'est là que vous voyez l'erreur d'héritage.

Comparez ces façons d'instancier une classe:

scala> class A 
defined class A 

scala> new A 
res0: A = [email protected] 

scala> new A {} 
res1: A = [email protected] 

scala> new {} with A 
res2: A = [email protected] 

scala> res1.getClass 
res3: Class[_ <: A] = class $anon$1 

scala> res2.getClass 
res4: Class[_ <: A] = class A 

scala> res0.getClass 
res5: Class[_ <: A] = class A 

scala> val a: A = res1 
a: A = [email protected] 

Notez que le type de res1 par rapport aux autres resX - il est anonyme, mais il ne couvre A et peut être utilisé à la place de A.

+0

Pourquoi avez-vous utilisé le mot clé ici? Pouvons-nous l'utiliser avec classe aussi? parce que je sais que c'est réservé pour trait! @Aleksey – SaKou

+0

Je voulais juste montrer différentes façons d'instancier la classe, mais dans le but de cette réponse 'with 'n'est pas nécessaire. –