C++ a un héritage multiple simple, de nombreux modèles de langage l'interdisent comme dangereux. Mais certains langages comme Ruby et PHP utilisent une syntaxe étrange pour faire la même chose et l'appellent mixins ou traits. J'ai entendu à plusieurs reprises que les mixins/traits sont plus difficiles) à l'abus que l'héritage multiple simple.
Qu'est-ce qui les rend spécifiquement moins dangereux? Y a-t-il quelque chose qui n'est pas possible avec les mixins/traits mais possible avec l'héritage multiple de style C++? Est-il possible de rencontrer le problème des diamants avec eux?
Cela semble comme si nous utilisions l'héritage multiple mais juste en faisant des excuses que ce sont des mixins/traits afin que nous puissions les utiliser.
Il existe un certain nombre de problèmes avec l'héritage multiple lorsqu'il est utilisé avec des classes à part entière, mais ils tournent tous autour de ambiguïté.
L'ambiguïté se manifeste de différentes manières:
x
, et que le type dérivé demande x
, qu'obtient-il? x
ont des types incongruents, vous pouvez en déduire.f
avec des signatures identiques et que quelqu'un appelle f
, qui est appelé? Et cela ignore des choses comme la répartition dynamique, l'inférence de type, la correspondance de modèles et d'autres choses que je connais moins et qui deviennent plus difficiles lorsque le langage prend en charge l'héritage multiple de classes complètes.
Les traits ou Mix-ins (ou interfaces, ou ...) sont tous des constructions qui spécifiquement limite les capacités d'un type afin qu'il n'y ait aucune ambiguïté. Ils rarement possèdent quoi que ce soit eux-mêmes. Cela permet à la composition des types d'être plus fluide car il n'y a pas deux variables ou deux fonctions ... il y a une variable et une référence; une fonction et une signature. Le compilateur sait quoi faire.
L'autre approche courante adoptée consiste à forcer l'utilisateur à "construire" (ou mélanger) son type un à la fois. Au lieu que les classes de base soient des partenaires égaux dans le nouveau type, vous ajoutez un type à un autre - en remplaçant tout ce qui était là (généralement avec une syntaxe facultative pour renommer et/ou réexposer les bits remplacés).
Y a-t-il quelque chose qui n'est pas possible avec les mixins/traits mais possible avec l'héritage multiple de style C++?
Selon le langage - il devient généralement difficile ou impossible de fusionner implémentations de fonctions et de stockage pour les variables de plusieurs classes de base et de les exposer dans le type dérivé.
Est-il possible de rencontrer un problème de diamant avec eux?
Parfois, des variations moins sévères apparaissent en fonction de votre langue, mais généralement non. L'intérêt des traits est de briser ce genre d'ambiguïté.