Pourquoi les frameworks Windows Forms / Swing favorisent-ils l'héritage plutôt que la composition?

12

Aujourd'hui, un de mes professeurs a déclaré qu'il trouvait étrange que bien que la philosophie de SWT soit de faire vos propres contrôles par composition, Swing semble favoriser l'héritage.

Je n'ai pratiquement aucun contact avec les deux frameworks, mais d'après ce dont je me souviens dans les formulaires Windows de C #, on étend généralement les contrôles, tout comme Swing.

Étant donné que généralement les gens ont tendance à préférer la composition à l'héritage, pourquoi les gens Swing / Windows Forms n'ont-ils pas préféré la composition plutôt que l'héritage?

Elysium dévoré
la source
2
Beaucoup de choses ont changé au cours des 15 à 20 dernières années, ces API existent! Les moteurs de rendu n'avaient pas de colle XML magique pour lier les objets d'écran aux instances de n'importe quelle classe concrète arbitraire "dans le temps";)
1
La plupart des codes Swing que je vois utilisent une extension par composition. Je ne sais pas où votre prof obtient ses données.
J'ai moi-même vu beaucoup de swing sur le net avec l'héritage au lieu de la composition - surtout des tutoriels. mais les formulaires Windows sont vraiment utilisés presque exclusivement par héritage!
dévoré elysium

Réponses:

7

JComponentexpose beaucoup de fonctionnalités . Si JComponentune interface et des composants ont été implémentés avec la composition, les composants simples devraient avoir des dizaines d'encapsuleurs de méthodes triviaux, par exemple

class MyComponent implements JComponent {
    JPanel panel;
    public boolean contains(int x, int y) {
        return panel.contains(x, y);
    }
    ...
}

Il y a aussi une raison d'efficacité de préférer l'héritage à la composition - la substitution ne coûte rien (en supposant qu'aucun superappel), tandis que la composition coûte un supplément INVOKEVIRTUAL. Je ne sais pas si cela a influencé la conception de Swing, mais c'est une grande préoccupation pour les cours de collection.

Daniel Lubarov
la source
2

Le Swing Framework est en fait conçu conformément au modèle de conception composite. Certes, il y a beaucoup d'héritage là-dedans, mais vous composez généralement vos propres formes en utilisant la composition. En d'autres termes, un formulaire est une composition de conteneurs et de contrôles de niveau intermédiaire.

Vincent Ramdhanie
la source
"Autrement dit, un formulaire est une composition de conteneurs et de contrôles de niveau intermédiaire." Sûr. Mais ce que je vois généralement, c'est que lorsque les gens veulent créer leur propre fenêtre (ou tout ce qui est appelé dans Swing), ils hériteront d'une classe de fenêtre au lieu d'utiliser la composition.
dévoré elysium
@devoured elysium C'est vrai. Mais pour créer la forme, ils utiliseraient la composition. C'est donc un peu d'héritage et beaucoup de composition.
@devoured, je pense que c'est un cas de personnes ne réalisant pas que le didacticiel qu'ils utilisent ne suit pas les meilleures pratiques, car il favorise la brièveté.
Peter Taylor
1

Avec Java, il est beaucoup plus facile de finir par utiliser l'héritage simplement parce que tout est virtuel. Besoin de corriger une "fonctionnalité" dans JTable / JFrame? Étendez-le, remplacez les méthodes problématiques, puis utilisez votre table / cadre partout à la place.

Je pense qu'avec des choses comme WPF, où la liaison de données est une caractéristique principale de la conception, il est beaucoup plus facile de faire de la composition au lieu de l'héritage.

John Gardner
la source
Que voulez-vous dire par «tout est virtuel »?
Jonas
en java, chaque méthode est implicitement virtuelle (peut être surchargée). En C #, vous devez déclarer explicitement une méthode en tant que virtual, et pour la remplacer, vous la déclarez explicitement en tant que override. En java, vous pouvez remplacer tout ce que vous pouvez voir et vous pouvez augmenter sa visibilité dans une sous-classe (vous pouvez rendre les méthodes protégées publiques dans une sous-classe!)
John Gardner
Notez que vous ne pouvez pas remplacer une finalméthode en Java, même si la classe de base elle-même ne l'est pas final.
perp
c'est vrai @perp. mais en java, vous devez sortir de votre chemin (ajout final) pour empêcher le virtuel. C # est le chemin inverse, vous devez vous démener pour être virtuel. Et un très petit pourcentage du runtime java standard est marqué comme final.
John Gardner
1

Dans Effective Java , article 17, Bloch mentionne qu'une classe conçue pour l'héritage "doit documenter son auto-utilisation des méthodes remplaçables". Une caractéristique de cela est l'expression de cette mise en œuvre . Vous le verrez dans des classes comme JTableet JInternalFrame. C'est une mesure de l'héritage par conception dans Swing.

poubelle
la source
-2

De C # 3.5, nous avons un concept appelé méthodes d'extension qui permet le concept de composition plutôt que l'héritage.

Dans ce processus, nous implémentons une fonctionnalité étendue à une classe existante simplement en ajoutant une classe d'extension qui rend la nouvelle fonctionnalité à la classe existante.

Vous pouvez vous référer ici pour plus de détails

Saravanan
la source
Je ne vois pas la pertinence de créer de nouvelles classes de contrôle WinForms. Pourriez-vous élaborer?
Peter Taylor
@Peter: Ceci n'est pas lié uniquement aux classes Windows Forms. Cela peut également s'appliquer à partir de notre code. Vous pouvez étendre n'importe quelle classe existante en ajoutant simplement une classe statique, puis en ajoutant une nouvelle méthode avec le 1er argument comme ceci afin que l'objet de base puisse être lié. Après avoir compilé le code, vous obtenez la méthode nouvellement ajoutée en tant que méthode de la classe de base elle-même. C'est ce que dit la composition. j'espère que j'ai raison ..
Saravanan
1
Je sais ce que sont les méthodes d'extension, et elles sont parfois très pratiques, mais cette question concerne différentes approches pour créer de nouvelles classes.
Peter Taylor
@Peter: Ensuite, je ne peux que signaler l'utilisation de classes partielles uniquement, à part cela, à ma connaissance, C # n'a pas d'autre caractéristique remarquable. Si vous en connaissez, merci de me le faire savoir.
Saravanan