J'ai récemment commencé à regarder Android Développement. Cela m'a ramené dans le monde du développement logiciel Java. La dernière fois que j'ai travaillé avec Java, j'avouerai, je n'ai pas compris OOP presque autant que (je pense) je fais maintenant.
Avoir principalement utilisé C # dans ma carrière, je remarque une différence surprenante dans la manière dont l'héritage est utilisé Java et c #.
En C #, il semblait que l'héritage puisse être évité dans la plupart des situations. La tâche à accomplir pourrait généralement être accomplie en utilisant des classes concrètes du . Net Cadre.
En Java, de ce que je suis rassemblant des échantillons de code, il semble que le cadre Java fournit de nombreuses interfaces ou classes abstraites qui sont alors destinées à être mises en œuvre/prolongées par le développeur.
Cela semble être une trop grande différence pour faire bouillir au style. Quel est le raisonnement derrière cela? Je me sens comme si je n'écrirai pas propre Java code jusqu'à ce que je comprends cela.
En outre, est-ce limité au juste le Android SDK ou est-ce une approche java à l'échelle de l'OOP?
Ou mis d'une autre manière,
De quoi s'agit-il de la conception de ces deux langues qui (semble encourager) plus ou moins d'utilisation de l'héritage que l'autre?
Si les langues traitent l'héritage de manière identique et que mon observation est valide, cela signifie que cela est lié à la conception des cadres/bibliothèques et non des langues. Quelle serait la motivation pour ce type de conception?
Cela semble être une trop grande différence pour faire bouillir au style. Quel est le raisonnement derrière cela?
Je crois comprendre que c'est largement est simplement une décision stylistique. Eh bien, peut-être pas de style, mais les idiomes de la langue/de l'environnement. Java Les développeurs de bibliothèque standard ont suivi un ensemble de directives de conception et les développeurs .NET une autre (bien qu'ils avaient la capacité de voir comment l'approche de Java a fonctionné).
Il y a très peu dans les langues actuelles pour encourager ou dissuader l'héritage. Seules deux choses me frappent comme pertinentes:
.NET introduit des génériques plus tôt dans leur vie, avant que trop de code non générique n'a été mis en œuvre. L'alternative est beaucoup d'héritage pour taper des choses spécialisées.
Un changement plus important était que .NET soutenait les délégués. In Java vous êtes coincé avec (anonyme) héritage pour fournir le plus fondamental de fonctionnalités variables. Cela conduit à une différence relativement grande 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 maladroites nécessaires pour le faire en Java.
Ce sont des langues très différentes, en particulier dans ce domaine. Disons que vous avez une classe. Dans ce cas, nous en ferons un contrôle de l'utilisateur, 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 exemple CleverPanel voudra savoir sur les choses qui se produisent dans son instance d'Uicontrol pour diverses raisons. Comment faire cela?
Dans C #, l'approche de base consiste à rechercher divers événements, à configurer des méthodes qui exécuteront lorsque chaque événement intéressant est déclenché. En Java, qui manque d'événements, la solution habituelle consiste à adopter un objet avec diverses méthodes de manutention "événement" à une méthode UICONTROL:
boolean stillNeedIt = ... ;
uiControl.whenSomethingHappens( new DoSomething() {
public void resized( Rectangle r ) { ... }
public boolean canICloseNow() { return !stillNeedIt; }
public void closed() { ... }
...
} );
Jusqu'à présent, la différence entre C # et Java n'est pas profonde. Cependant, nous avons l'interface de dosage qui n'est pas nécessaire dans C #. En outre, cette interface pourrait 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, DosomethyDapter. Maintenant, nous remplaçons Dosomething avec Dosomethy LootPaetter et nous n'avons pas besoin d'écrire des méthodes pour une compilation propre. Nous finissons simplement à remplacer les méthodes que nous devons faire fonctionner le programme. Nous finissons donc à avoir besoin d'une interface et Utilisation de l'héritage dans Java pour correspondre à ce que nous avons fait avec des événements en C #.
C'est un exemple, pas une discussion globale, mais elle donne les bases de la raison pour laquelle il y a tellement de héritage dans Java par opposition à c #.
Maintenant, pourquoi Java fonctionne-t-il de cette façon? La flexibilité. L'objet transmis à WhensomohatHappens aurait pu être transmis à CleverPanel de quelque part d'ailleurs. Cela pourrait être quelque chose que plusieurs instances CleverPanel doivent passer à leurs objets de type UICONTROL pour aider un objet CleverWindow à quelque part. ou L'UICONTROL pourrait le remettre à l'un des c'est Composants.
De plus, au lieu d'un adaptateur, il pourrait y avoir une implémentation de dosage quelque part avec des milliers de lignes de code derrière elle. Nous pourrions créer une nouvelle instance de ça et le transmettre. Nous devrions peut-être remplacer une méthode. Un tour commun dans Java est d'avoir une grande classe avec une méthode comme:
public class BigClass implements DoSomething {
...many long methods...
protected int getDiameter() { return 5; }
}
Puis à cleverlanel:
uiControl.whenSomethingHappens( new BigClass() {
@Override
public int getDiameter() { return UIPanel.currentDiameter; }
} );
La plate-forme open source Java fait beaucoup de cela, ce qui tend à pousser des programmeurs à faire plus davantage - les deux, car ils le suivent comme exemple et simplement pour l'utiliser. Je pense que la conception de base de la langue est derrière Sun's Framed Design et Derrière le programmeur Java Utilise les techniques lorsque non Utilisation du cadre.
C'est vraiment facile de créer une classe à la volée de Java. La classe, anonyme ou nommée, ne doit être référencée que dans un petit bloc de code enterré profondément dans une méthode. Il peut être créé complètement neuf ou de légères modifications à une classe existante très importante. (Et la classe existante peut être de haut niveau dans son propre fichier, ou imbriqué dans une classe de niveau supérieur ou défini uniquement dans un seul bloc de code). La nouvelle instance de classe peut avoir un accès complet à toutes les données de la création de l'objet. Et la nouvelle instance peut être transmise et utilisée dans tout le programme, représentant l'objet qui l'a créé.
(En bar de côté, notez qu'une grande utilisation de l'héritage ici - comme dans d'autres endroits de Java - est simplement pour des objectifs DRY. Il permet de réutiliser différentes classes de réutiliser le même code. Notez également la facilité d'héritage dans Java qui encourage ceci.)
Encore une fois, ce n'est pas une discussion globale; Je me gratte juste la surface ici. Mais oui, Il y a une différence surprenante dans la manière dont l'héritage est utilisé entre Java et C #. Ils sont, à cet égard, des langues très différentes. Ce n'est pas votre imagination.