2010-09-03 6 views
6

Je rencontre un comportement étrange par la gestion par Scala des constructeurs de super-classes.Scala: invocation du constructeur de la superclasse

J'ai une classe très simple définie de la manière

package server 

class Content(identifier:String,content:String){ 
    def getIdentifier() : String = {identifier} 
    def getContent() : String = {content} 
} 

et une sous-classe simple,

package server 

class SubContent(identifier:String, content:String) extends Content(identifier, content+"XXX")){ 

    override def getContent():String = { 
     println(content) 
     super.getContent 
    } 
} 
suivant

Ce qui est vraiment étrange est que dans la sous-classe il y a des doublons des attributs superclasse, donc si je crée un nouvel objet

var c = new SubContent("x","x") 

l'exécution de

c.getContent 

premières impressions sur « x » (La valeur fournie au constructeur de sous-classe), mais retourne « Xxxx » (La valeur fournie au constructeur superclasse).

Est-il possible d'éviter ce comportement? Fondamentalement ce que je voudrais avoir, c'est que la sous-classe ne crée pas ses propres attributs, mais passe simplement les paramètres à la superclasse.

Répondre

8

Il fait exactement ce que vous lui avez demandé de faire. Vous avez augmenté le paramètre du second constructeur en le transmettant au constructeur de la superclasse, puis vous avez utilisé la superclasse 'getContent pour fournir la valeur renvoyée par la sous-classe' getContent. Ce qu'il faut savoir, c'est que les paramètres constructeur (ceux qui ne sont pas liés aux propriétés parce qu'ils font partie d'un case class ou parce qu'ils ont été déclarés avec le mot-clé val) sont dans la portée du corps de la classe. Le constructeur de la classe est la partie de son corps qui est en dehors de n'importe quelle méthode. Ainsi, les références aux paramètres du constructeur dans les corps de méthode forcent le paramètre constructeur à être stocké dans un champ afin qu'il puisse avoir l'étendue nécessaire. Notez que votre appel println dans getContent provoque un tel champ de paramètre constructeur masqué dans ce cas.

Répondre au commentaire « Y at-il une autre façon de le définir afin d'éviter cela? Ou du moins, si je ne réfère aux paramètres de la sous-classe des constructeurs leurs champs seront attribués (mémoire émaciation)? » Si les seules références aux paramètres constructeur simples (*) sont dans le constructeur propre (c'est-à-dire en dehors de tout corps de méthode, et val et var initialiseurs ne sont pas considérés comme des corps de méthode), aucun champ invisible ne sera créé pour maintenez le paramètre constructeur. Cependant, s'il y a plus que vous essayez d '"éviter" que ces champs invisibles, je ne comprends pas ce que vous demandez. (*) Par "paramètres de constructeur simples", j'entends ceux qui ne font pas partie d'une classe de cas et qui ne portent pas le mot-clé val.

+0

Il ne s'agit pas d'une classe de cas, mais le problème persiste, notamment parce que 'content' est utilisé dans le corps de la sous-classe. –

+0

Existe-t-il une autre façon de le définir pour éviter cela? Ou du moins, si je ne me réfère jamais aux paramètres des constructeurs de sous-classes, leurs champs seront alloués (Mémoire de gaspillage)? – mariosangiorgio

+3

Utilisez 'super.content' au lieu de simplement' content' dans 'SubContent.getContent'. –

Questions connexes