J'aimerais avoir un trait qui peut a) être mélangé dans n'importe quelle classe avec une méthode particulière, et b) peut appeler Super. Quelque chose comme ceci: existe-t-il un moyen de faire cela? P> Notez que je ne contrôle pas A et B; Ils viennent d'une autre bibliothèque que je ne peux pas modifier. p> [Modifier - ajouté après avoir vu des réponses] p> est là un moyen d'appeler la méthode d'origine dans quelque chose comme ça? p> trait ImplementsStuff {
this: HasStuffMethod =>
abstract override def stuff = "foo" + "how do I call the original method here?"
}
3 Réponses :
Vous avez besoin d'un abstraite remplacement code> dans un tel cas. P>
Comment définissez-vous le trait? (Ajout d'une note indiquant que la ligne "Traiter ImplementsStuffstuffs étend HastuffmeThod" ne compile pas.)
@Jamesmoore Just Résumé Supprimer Def ... Code>. Mais je viens de remarquer que vous l'avez d'émettre un type code> - code> - code> est juste un alias, et votre alias est un type structurel: cela ne fonctionnera pas. Faites prolonger un Classe abstraite code> à la place ou un trait code>.
Je peux penser à deux options:
option 1, à l'aide d'une annotation de type auto-type et d'appel option 2 (puisque vous dites que vous ne contrôlez pas A et B) est le cher ancien modèle de décorateur. P> Stuff code> à partir d'une nouvelle méthode (que j'appelle imaginativement appelée CallStuff code>) de le remplacer. p> trait HasStuff { def stuff: String }
class DecorateStuff(decorated: HasStuffMethod) extends HasStuff {
def stuff = "trait + " + decorated.stuff
}
val decA = new DecorateStuff(new A)
assert(decA.stuff == "trait + a stuff")
val decB = new DecorateStuff(new B)
assert(decB.stuff == "trait + b stuff")
Les deux intéressants, mais ni ne résout le problème. Le premier échoue car il n'ya aucun moyen de dire à tous les appelants qu'ils doivent appeler une nouvelle méthode (et donc les affirmations échouent définitivement). La seconde renvoie un type différent, il s'agit donc d'une technique utile, mais cela ne vous aide pas vraiment ici - que faites-vous que vous faites lorsque vous devez passer la nouvelle chose à un autre code qui attend un A, pas un décoratestuff?
@Jamesmoore Vous avez raison, les deux méthodes supposent que vous / votre équipe contrôlent le code de l'appelant. Si ce n'est pas le cas et que vos attentes sont de modifier le comportement de leur méthode de substance, mais ont toujours A et B, cela ressemble à une programmation orientée forme. Vous pouvez regarder AspectJ. Cet article de Jonas Boner peut vous aider
C'est juste que le système existant semble soooo i> près de ce que je voudrais. Dans votre premier exemple, si vous pouviez modifier CallStuff au bout des trucs ordinaires, puis avoir un moyen de référencer la méthode étant remplacée, vous l'auriez. (Ajouté que à ma question)
Il n'y a aucun moyen d'étendre un type raffiné dans Scala (je ne suis pas sûr que cela pourrait être retiré en toute sécurité, mais il serait intéressant d'explorer).
J'ai une solution plus verbeuse, mais vous rapproche de votre objectif. P>
$ a.stuff res0: java.lang.String = trait + a stuff $ b.stuff res1: java.lang.String = trait + b stuff
Ici
Hassffmethod code> n'est pas une classe de type. C'est un alias de type à un type structurel.Droit - un modèle de typlass est autre chose. Et il n'est pas pertinent de savoir si
hasstuffmethod code> est un type structurel ou nominal (c'est-à-dire un trait régulier).J'ai ajouté une modification proposée à votre question. J'espère que cela clarifie ce que vous essayez de faire. Si j'ai mal interprété, vous pouvez l'effacer. Si c'est correct, vous pouvez l'utiliser pour reformuler votre question. Dans ce cas, veuillez également modifier la référence à "Typemass" dans le titre de la question.
@Paolofalabella, je pense que je vois où vous allez, mais je pense que la modification proposée ne le rend pas vraiment plus clair. Il est toujours faux de répéter le code, il y a donc une grosse morceine de l'édition proposée qui doit disparaître et je ne pense pas que ce qui reste est vraiment différent de l'original. Certainement, la référence à la typlass dans mon original n'est pas fausse et je vais le réparer. (A suscité votre commentaire)
Je pense avoir ce que vous demandiez, mais cela m'a semblé que Daniel C.Sobral et paradigmatique ne l'ont pas fait. Comme ils sont tous deux beaucoup plus experts à Scala que moi, je pensais que peut-être reharaser votre question pourrait vous obtenir une meilleure réponse que la mienne. Cependant, vous avez probablement raison que mon édition proposée n'était pas vraiment une amélioration.