Ich habe vor kurzem angefangen, mich mit Android-Entwicklung zu beschäftigen. Dies hat mich zurück in die Welt der Java-Softwareentwicklung geführt. Das letzte Mal, als ich mit Java gearbeitet habe, habe ich OOP zugegebenermaßen nicht annähernd so gut verstanden wie jetzt (glaube ich).
Nachdem ich in meiner Karriere hauptsächlich C # verwendet habe, bemerke ich einen verblüffenden Unterschied in der Verwendung von Java und C # bei der Vererbung.
In C # schien die Vererbung in den meisten Situationen vermieden werden zu können. Die vorliegende Aufgabe kann normalerweise mithilfe konkreter Klassen des .NET- Frameworks ausgeführt werden.
In Java sieht es so aus, als ob das Java-Framework viele Schnittstellen oder abstrakte Klassen enthält, die vom Entwickler implementiert / erweitert werden sollen.
Dies scheint ein zu großer Unterschied zu sein, als dass man sich auf den Stil beschränken könnte. Was ist die Begründung dafür? Ich habe das Gefühl, dass ich keinen sauberen Java-Code schreiben werde, bis ich das verstanden habe.
Beschränkt sich dies nur auf das Android SDK oder handelt es sich um einen Java-weiten Ansatz für OOP?
Oder anders ausgedrückt:
Was ist mit dem Design dieser beiden Sprachen, das (anscheinend) mehr oder weniger Vererbung fördert als die andere?
Wenn die Sprachen die Vererbung identisch behandeln und vorausgesetzt, dass meine Beobachtung gültig ist, dann bedeutet dies, dass dies mit dem Design der Frameworks / Bibliotheken zusammenhängt und nicht mit den Sprachen. Was wäre die Motivation für diese Art von Design?
quelle
Antworten:
Mein Verständnis ist , dass es im Wesentlichen ist einfach eine stilistische Entscheidung. Na ja, vielleicht nicht Stil, sondern die Redewendungen der Sprache / Umgebung. Entwickler von Java-Standardbibliotheken befolgten eine Reihe von Designrichtlinien und die .NET-Entwickler eine andere (obwohl sie die Möglichkeit hatten, zu sehen, wie Javas Ansatz funktionierte).
In den eigentlichen Sprachen gibt es sehr wenig, um die Vererbung zu fördern oder abzubringen. Nur zwei Dinge erscheinen mir relevant:
.NET führte Generika früher in ihrem Leben ein, bevor zu viel nicht generischer Code implementiert wurde. Die Alternative ist viel Vererbung, um Dinge zu spezialisieren.
Eine größere Änderung war, dass .NET Delegaten unterstützt. In Java stecken Sie in der (anonymen) Vererbung, um die grundlegendste Variablenfunktionalität bereitzustellen. Dies führt zu einem relativ großen Unterschied in der Art und Weise, wie Code entwickelt wurde, um entweder die Vorteile von Delegaten zu nutzen oder um die umständlichen Vererbungsstrukturen zu vermeiden, die für die Ausführung in Java erforderlich sind.
quelle
Dies sind sehr unterschiedliche Sprachen, insbesondere in diesem Bereich. Nehmen wir an, Sie haben eine Klasse. In diesem Fall machen wir daraus ein Benutzersteuerelement, so etwas wie ein Textfeld. Nennen Sie es UIControl. Jetzt wollen wir das in eine andere Klasse einordnen. Da wir in diesem Fall eine Benutzeroberfläche für unser Beispiel verwenden, nennen wir sie die CleverPanel-Klasse. Unsere CleverPanel-Instanz möchte aus verschiedenen Gründen wissen, was mit ihrer UIControl-Instanz passiert. Wie macht man das?
In C # besteht der grundlegende Ansatz darin, nach verschiedenen Ereignissen zu suchen und Methoden einzurichten, die ausgeführt werden, wenn jedes interessante Ereignis ausgelöst wird. In Java, in dem es an Ereignissen mangelt, besteht die übliche Lösung darin, ein Objekt mit verschiedenen "Ereignis" -Behandlungsmethoden an eine UIControl-Methode zu übergeben:
Bisher ist der Unterschied zwischen C # und Java nicht tiefgreifend. Wir haben jedoch die DoSomething-Schnittstelle, die in C # nicht benötigt wird. Außerdem enthält diese Schnittstelle möglicherweise viele Methoden, die die meiste Zeit nicht benötigt werden. In C # behandeln wir dieses Ereignis einfach nicht. In Java erstellen wir eine Klasse, die eine Null-Implementierung für alle Schnittstellenmethoden bereitstellt, DoSomethingAdapter. Jetzt ersetzen wir DoSomething durch DoSomethingAdapter und müssen für eine saubere Kompilierung überhaupt keine Methoden schreiben. Am Ende überschreiben wir nur die Methoden, die wir benötigen, damit das Programm richtig funktioniert. Daher benötigen wir eine Schnittstelle und verwenden Vererbung in Java, um das, was wir getan haben, mit Ereignissen in C # abzugleichen.
Dies ist ein Beispiel, keine umfassende Erörterung, aber es enthält die Grundlagen, warum Java im Gegensatz zu C # so viel vererbt.
Warum funktioniert Java so? Flexibilität. Das Objekt wurde übergeben, wenn Something Happens vollständig an CleverPanel übergeben werden konnte. Möglicherweise sollten mehrere CleverPanel-Instanzen an ihre UIControl-ähnlichen Objekte übergeben werden, um irgendwo ein CleverWindow-Objekt zu unterstützen. Oder die UIControl könnte es an eine ihrer Komponenten übergeben.
Anstelle eines Adapters kann es auch eine DoSomething-Implementierung geben, die Tausende von Codezeilen enthält. Wir könnten eine neue Instanz erstellen , dass es passieren. Möglicherweise müssen wir eine Methode überschreiben. Ein häufiger Trick in Java ist, eine große Klasse mit einer Methode wie der folgenden zu haben:
Dann in CleverlPanel:
Die Open-Source-Java-Plattform leistet einen großen Beitrag dazu, dass Programmierer mehr tun - sowohl, weil sie dem Beispiel folgen als auch einfach, um es zu nutzen. Ich denke, dass das grundlegende Design der Sprache hinter dem Framework-Design von Sun und hinter dem Einsatz der Techniken durch Java-Programmierer steckt, wenn das Framework nicht verwendet wird.
In Java ist es ganz einfach, eine Klasse im laufenden Betrieb zu erstellen. Die Klasse, anonym oder benannt, muss nur in einem kleinen Codeblock referenziert werden, der tief in einer Methode vergraben ist. Es kann komplett neu erstellt werden oder durch geringfügige Änderungen an einer sehr großen, vorhandenen Klasse. (Und die vorhandene Klasse kann sich auf oberster Ebene in ihrer eigenen Datei befinden oder in einer Klasse auf oberster Ebene verschachtelt sein oder nur innerhalb eines einzelnen Codeblocks definiert sein.) Die neue Klasseninstanz kann vollen Zugriff auf alle Daten des erstellenden Objekts haben. Die neue Instanz kann im gesamten Programm übergeben und verwendet werden und stellt das Objekt dar, von dem sie erstellt wurde.
(Beachten Sie außerdem, dass die Vererbung in großem Umfang hier - wie auch an anderen Stellen in Java - nur zu DRY-Zwecken verwendet wird. Verschiedene Klassen können denselben Code wiederverwenden. Beachten Sie auch die einfache Vererbung in Java, die dies fördert. )
Auch dies ist keine umfassende Diskussion. Ich kratz hier nur an der Oberfläche. Aber ja, es gibt einen verblüffenden Unterschied in der Verwendung der Vererbung zwischen Java und C #. Sie sind in dieser Hinsicht sehr unterschiedliche Sprachen. Es ist nicht deine Einbildung.
quelle
Es gibt absolut keinen Unterschied in der Art und Weise, wie die Vererbung zwischen Java und C # behandelt wird. Wann Sie tatsächlich Vererbung oder Komposition verwenden, ist definitiv eine Entwurfsentscheidung und keinesfalls etwas, das Java oder C # ermutigen oder entmutigen. Ich empfehle Ihnen, diesen Artikel zu lesen .
Hoffe ich habe geholfen!
quelle