2010-02-24 8 views
8

Essayer de définir une méthode accesseur pour le paramètre constructeur par défaut, à savoir:Comment définir la méthode accesseur pour le paramètre constructeur par défaut?

class Person (age: Int) { 
    def age: Int = this.age 
} 

Ce qui se traduit évidemment par une erreur du compilateur: référence ambiguë à la définition de surcharge, à la fois l'âge de la méthode en personne de classe de type => Int et valeur age in class Personne de type Int correspond au type attendu Int

Y a-t-il un moyen, dans ce contexte, de faire la distinction entre le nom de la méthode du membre et le nom de la valeur du membre généré automatiquement?

Bien sûr, il est possible de changer le nom de l'un ou l'autre des identificateurs, mais y a-t-il un moyen dans ce scénario de spécifier à quel identifiant on fait référence?

Répondre

16

Placez simplement "val" devant les paramètres du constructeur que vous souhaitez exposer en tant que propriétés d'instance.

+0

Merci! Je l'ai compris moi-même.:-) Mais que faire si je voulais remplacer l'accesseur par défaut? Je suppose que je devrais encore renommer le paramètre? –

+3

Oui, vous devez renommer le paramètre (par exemple 'age0'), puis définir l'accesseur' def age = {Math.abs (age0) ' – retronym

6

Utilisez

class Person (val age: Int) 

si vous voulez juste un getter ou

class Person (var age: Int) 

si vous voulez aussi un poseur.

3

Les réponses ci-dessus sont excellentes par rapport au principe d'accès uniforme. Si vous avez ou avez besoin de getters et setters de style Java, vous pouvez également utiliser l'annotation BeanProperty.

class Person(@scala.reflect.BeanProperty var age: Int) 

Cela se traduira par les méthodes suivantes en cours de création:

def getAge: Int = age 
def setAge(age: Int) = this.age = age 

Si vous utilisez plutôt le BeanProperty pour un val au lieu d'un var, le poseur ne sera pas créé, seul le getter. Un autre avertissement, la méthode de setter ne peut pas être appelée à partir de Scala. Au lieu de cela, vous devez utiliser la convention Scala standard d'accès uniforme pour définir la valeur.

1

Juste pour l'exhaustivité et pour développer les réponses précédentes, il y a aussi la technique here.

Pour résumer, je commence toujours par une valeur immuable:

class Person (val age: Int) 

Ensuite, si vous comprenez que vous devez muter la valeur (ou vous le savez à l'avance), passez à:

class Person (var age: Int) 

Ensuite, si vous avez besoin de valider ou faire un autre calcul sur obtenir ou de définir, renommer votre variable et construire des accesseurs qui imitent votre dénomination d'origine, pas besoin de refactoriser le reste du code:

class Person(var _age: Int) 
{ 
    def age = 
    { 
     println("age requested") 
     _age 
    } 
    def age_=(newAge: Int) = 
    { 
     assert(newAge > 0) 
     println(s"age changed from ${_age} to $newAge") 
     _age = newAge 
    } 
} 

Bien sûr, vous pouvez simplifier setter ou getter si vous n'avez pas besoin d'opérations là-bas.

Félicitations à toutes les autres réponses, qui sont en effet correctes et sont venues beaucoup plus tôt.

Questions connexes