J'ai récemment commencé à regarder le développement Android. Cela m'a ramené dans le monde du développement de logiciels Java. La dernière fois que j’ai travaillé avec Java, je l’avouerai, je ne comprenais pas autant la POO que je le pense maintenant.
Ayant principalement utilisé le C # dans ma carrière, je remarque une différence surprenante dans l'utilisation de l'héritage en Java et C #.
En C #, il semblait que l'héritage pouvait être évité dans la plupart des situations. La tâche à accomplir peut généralement être accomplie en utilisant des classes concrètes du framework .NET .
En Java, d'après ce que je récupère à partir d'exemples de code, le framework Java fournit de nombreuses interfaces ou classes abstraites qui doivent ensuite être implémentées / étendues par le développeur.
Cela semble être une trop grande différence pour se résumer à un style. Quel est le raisonnement derrière cela? Je sens que je n'écrirai pas de code Java propre tant que je ne l'aurai pas compris.
En outre, est-ce limité au SDK Android ou s'agit-il d'une approche de la POO à l'échelle de Java?
Ou en d'autres termes,
Qu'y a-t-il dans la conception de ces deux langages qui (semble encourager) l'utilisation plus ou moins héréditaire de l'autre?
Si les langues traitent l'héritage de manière identique, et en supposant que mon observation soit valide, cela signifie alors que cela est lié à la conception des frameworks / bibliothèques et non aux langues. Quelle serait la motivation pour ce type de design?
la source
Réponses:
Je crois comprendre qu'il en grande partie est tout simplement une décision stylistique. Eh bien, peut-être pas le style, mais les idiomes de la langue / de l'environnement. Les développeurs de bibliothèques standard Java ont suivi un ensemble de directives de conception et les développeurs .NET un autre (bien qu’ils aient eu la possibilité de voir comment l’approche de Java fonctionnait).
Il y a très peu de choses dans les langues actuelles pour encourager ou dissuader l'héritage. Deux choses me semblent pertinentes:
.NET a introduit les génériques plus tôt dans leur vie, avant que trop de code non générique ne soit implémenté. L'alternative est beaucoup d'héritage pour taper des choses spécialisées.
Un changement plus important a été que les délégués soutenus par .NET. En Java, l'héritage (anonyme) vous empêche de fournir les fonctionnalités de base les plus élémentaires. Cela conduit à une différence relativement importante dans la manière dont le code est conçu pour tirer parti des délégués ou pour éviter les structures d'héritage fastidieuses nécessaires pour le faire en Java.
la source
Ce sont des langues très différentes, particulièrement dans ce domaine. Disons que vous avez une classe. Dans ce cas, nous allons en faire un contrôle utilisateur, quelque chose comme une zone de texte. Appelez-le UIControl. Maintenant, nous voulons mettre cela dans une autre classe. Dans ce cas, puisque nous utilisons une interface utilisateur pour notre exemple, nous l'appellerons la classe CleverPanel. Notre instance CleverPanel voudra savoir ce qui se passe dans son instance UIControl pour diverses raisons. Comment faire ça?
En C #, l’approche de base consiste à rechercher différents événements, en définissant des méthodes à exécuter lorsque chaque événement intéressant est déclenché. En Java, où il manque des événements, la solution habituelle consiste à transmettre un objet avec différentes méthodes de traitement "d'événement" à une méthode UIControl:
Jusqu'à présent, la différence entre C # et Java n'est pas profonde. Cependant, nous avons l'interface DoSomething qui n'est pas nécessaire en C #. En outre, cette interface peut inclure de nombreuses méthodes qui ne sont pas nécessaires la plupart du temps. En C #, nous ne gérons tout simplement pas cet événement. En Java, nous créons une classe qui fournit une implémentation nulle pour toutes les méthodes d'interface, DoSomethingAdapter. Maintenant, nous remplaçons DoSomething par DoSomethingAdapter et nous n’avons besoin d’écrire aucune méthode pour une compilation propre. Nous finissons par ignorer les méthodes dont nous avons besoin pour que le programme fonctionne correctement. Nous finissons donc par avoir besoin d’une interface et d’ utiliser l’héritage en Java pour correspondre à ce que nous avons fait avec les événements en C #.
Ceci est un exemple, pas une discussion exhaustive, mais il explique en gros pourquoi il y a tant d'héritage en Java par opposition à C #.
Maintenant, pourquoi Java fonctionne-t-il de cette façon? Souplesse. L'objet transmis à whenSomethingHappens aurait pu être transmis à CleverPanel d'un autre endroit complètement. Plusieurs instances de CleverPanel doivent peut-être passer à leurs objets de type UIControl pour aider un objet CleverWindow quelque part. Ou bien UIControl pourrait le transférer à l’un de ses composants.
En outre, au lieu d'un adaptateur, il peut exister une implémentation de DoSomething comportant des milliers de lignes de code. Nous pourrions créer une nouvelle instance de cela et la transmettre. Nous pourrions avoir besoin de remplacer une méthode. Une astuce courante en Java est d’avoir une grande classe avec une méthode comme:
Puis dans CleverlPanel:
La plate-forme Java open source fait beaucoup de cela, ce qui a tendance à pousser les programmeurs à en faire plus - à la fois parce qu'ils suivent l'exemple et simplement pour l'utiliser. Je pense que la conception de base du langage repose sur la conception de la structure de Sun et sur celle du programmeur Java qui utilise les techniques sans utiliser la structure.
Il est très facile de créer une classe à la volée en Java. La classe, anonyme ou nommée, ne doit être référencée que dans un petit bloc de code enfoui au cœur d'une méthode. Il peut être créé complètement nouveau ou par de légères modifications d'une très grande classe existante. (Et la classe existante peut être de niveau supérieur dans son propre fichier, ou imbriquée dans une classe de niveau supérieur, ou définie uniquement dans un seul bloc de code). La nouvelle instance de classe peut avoir un accès complet à toutes les données de l'objet en cours de création. Et la nouvelle instance peut être transmise et utilisée dans tout le programme, représentant l'objet qui l'a créée.
(Soit dit en passant, notez qu'une grande utilisation de l'héritage ici - comme dans d'autres endroits en Java - est simplement destinée à la DRY. Cela permet à différentes classes de réutiliser le même code. Notez également la facilité d'héritage en Java qui l'encourage. )
Encore une fois, ce n’est pas une discussion complète; Je ne fais que gratter la surface ici. Mais oui, il existe une différence surprenante dans l'utilisation de l'héritage entre Java et C #. Ce sont des langues très différentes à cet égard. Ce n'est pas ton imagination.
la source
Il n'y a absolument aucune différence dans la gestion de l'héritage entre Java et C #. Lorsque vous utiliserez réellement l'héritage ou la composition, cela est définitivement une décision de conception et, en aucun cas, quelque chose que Java ou C # encourage ou décourage. Je vous suggère de lire cet article .
J'espère que j'ai aidé!
la source