Est-il possible d'ajouter une propriété ou une méthode à un objet de manière dynamique dans Groovy? C'est ce que j'ai essayé jusqu'à présent:
class Greet {
def name
Greet(who) { name = who[0].toUpperCase() + [1..-1] }
def salute() { println "Hello $name!" }
}
g = new Greet('world') // create object
g.salute() // Output "Hello World!"
g.bye = { println "Goodbye, $name" }
g.bye()
Mais je reçois l'exception suivante:
Hello World!
Caught: groovy.lang.MissingPropertyException: No such property: bye for class: Greet
Possible solutions: name
at test.run(greet.groovy:11)
Si vous souhaitez simplement ajouter la méthode bye()
à l'instance unique g
de la classe Greet
, vous devez faire:
g.metaClass.bye = { println "Goodbye, $name" }
g.bye()
Sinon, ajouter bye()
à toutes les instances de Greet
(à partir de maintenant), appelez
Greet.metaClass.bye = { println "Goodbye, $name" }
Mais vous auriez besoin de le faire avant de créer une instance de la classe Greet
Voici une page sur la métaclasse par instance
et voici la page sur les métaclasses en général
En outre, il y a un bogue dans votre constructeur. Vous manquez who
de l'infonte de votre [1..-1]
Et si le constructeur est passé un String
de moins de 2 caractères, il lancera une exception
Une meilleure version pourrait être:
Greet( String who ) {
name = who.inject( '' ) { String s, String c ->
s += s ? c.toLowerCase() : c.toUpperCase()
}
}
Comme métimisée dans les commentaires,
Greet( String who ) {
name = who.capitalize()
}
est la bonne façon