2015-12-13 1 views
3

J'essaie de trouver quelle est la différence entre mélanger des traits via le modèle de gâteau et de les mélanger via l'extension à l'ancienne. Voici mes deux exemples:Quels sont les avantages de l'approche gâteau en vertu de l'ancien mode étendu?

Via extension

trait X { 
    def foo() 
} 

trait Y extends X { 
    def bar() 
} 

class Z extends Y { 
    def foo() =() 
    def bar() =() 
} 

Et par gâteau

trait N { 
    def foo() 
} 

trait M { 
    this: N => 
    def bar() 
} 

class U extends M with N { 
    def bar() =() 
    def foo() =() 
} 

Quels sont les avantages de l'approche de gâteau? Ils sont tous deux les mêmes pour moi. Peut-être que je me trompe, mais je ne vois pas de différence significative.

Répondre

1

Si je veux enrichir les fonctionnalités de X, la première approche:

// I am X 
// I give you everything X provides 
trait Y extends X { 
    def bar() 
} 

Si je veux utiliser la fonctionnalité de N, je voudrais utiliser la deuxième approche:

// I am an extension of N 
// I require you to be N 
trait M { this: N => 
    def bar() 
} 

La principale Le bénéfice de "l'approche gâteau" par rapport à "l'ancienne mode" ne fixe pas la contrainte de hiérarchie à l'avance et évite (éventuellement) le problème du diamant en utilisant la "linéarisation de traits".

Les traits formant class U implémentés dans votre exemple sont résolus de droite à gauche. Avoir un ordre de résolution de méthode sain (MRO) nous donne la liberté de mélanger n'importe quel trait d'une «manière empilable».