2008-09-16 10 views
8

Ich habe gehört, dass es eine Möglichkeit gibt, einzelne Vererbung zu betrügen und Mehrfachvererbung in Java zu implementieren. Kann jemand das implementieren (ohne Verwendung von Schnittstelle)?Betrüge einzelne Vererbung in Java?

Nur aus Neugier ;-)

+0

Es ist ein ganz anderer Gedanke. – Warrior

Antwort

20

Sicher können Sie, aber es ist schwierig und Sie sollten wirklich darüber nachdenken, wenn das die Art ist, wie Sie gehen möchten.
Die Idee ist, Scope-basierte Vererbung gekoppelt mit typbasierten zu verwenden. Typisch ist, dass interne Klassen interne Klassen Methoden und Felder der äußeren Klasse "erben". Es ist ein bisschen wie Mixins, bei denen die äußere Klasse in die innere Klasse eingemischt ist, aber nicht so sicher, da Sie den Zustand der äußeren Klasse ebenso wie die Methoden ändern können.
Gilad Bracha (einer der wichtigsten Java-Sprache Designer) schrieb eine paper diskutieren, dass. Angenommen, Sie möchten einige Methoden für die interne Verwendung zwischen nicht verwandten Klassen freigeben (z. B. für die Zeichenfolgemanipulation), können Sie Unterklassen von ihnen als innere Klassen einer Klasse mit allen erforderlichen Methoden und den Unterklassen erstellen verwende Methoden sowohl von ihren Super-Klassen als auch von der äußeren Klasse.

Wie auch immer, es ist für komplexe Klassen heikel, und man konnte die meisten Funktionen mit statischen Importen (von Java 5 auf) erhalten. Gute Frage für Vorstellungsgespräche und Pub Quizzes, aber ;-)

+0

Dies ist, was ich wirklich brauchte..mit inneren Klassen..thanks – Omnipotent

+1

gibt es einen kleinen Tippfehler hier, ich würde es beheben, aber ich habe noch nicht genügend rep . 'Erstelle Unterklassen von THEN as' – TygerKrash

+0

@TygerKrash Du benötigst kein Rep um Posts zu bearbeiten: SE soll wie ein Wiki sein. –

0

JAVA unterstützt nicht mehr inheritence.

Sie können es erhalten, um mehrere Schnittstellen zu implementieren, und einige sehen dies als eine Möglichkeit, das Problem zu umgehen. Persönlich habe ich noch mehrfache Erbschaft, so dass ich seine Attraktivität nicht wirklich verstehen kann.

Normalerweise, wenn jemand mehrere Vererbung in C# oder JAVA vorschlägt, aufgrund der Tatsache, dass sie in C++ könnten. Ich bin ein Fan von "nur weil du es nicht meinen kannst". Als C# & JAVA unterstützt es nicht, warum versuchen Sie es zu zwingen, etwas zu tun, für das es nicht entwickelt wurde. Das soll nicht heißen, dass es einzigartige Fälle gibt, in denen es eine gültige Technik für empoly ist, nur der Code kann normalerweise refaktorisiert werden, um ihn nicht zu benötigen.

+0

Sie meinen wahrscheinlich, dass es * multiple * Vererbung nicht unterstützt. –

+0

Trait Vererbung (im Wesentlichen Mixin Vererbung) in Scala zeigt ein paar Möglichkeiten, in denen mehrere Vererbung nützlich sein kann, obwohl Javas Entscheidung, es nicht zu implementieren, verständlich ist, da viele Implementierungen unnötig komplex sind, um darüber nachzudenken. – Calum

4

Die Verwendung von Zusammensetzung anstelle von Vererbung neigt dazu, der Weg um diese zu sein. Dies hilft auch sehr bei der Testbarkeit, also ist es eine gute Übung im Allgemeinen.

Wenn Sie nur möchten, dass sich Ihr Typ wie mehrere andere Typen verhält, können Sie von so vielen Schnittstellen erben, wie Sie möchten; Sie können jedoch offensichtlich keine Implementierungsdetails von diesen "ausleihen".

1

Verwenden Sie interface s. Sie können so viele implementieren, wie Sie möchten. Sie können normalerweise eine Variante auf der Composite Pattern (GoF) verwenden, um Implementierungscode wiederverwenden zu können, wenn dies wünschenswert ist.

3

Ich glaube, dass der Grund, warum Java keine Mehrfachvererbung unterstützt, derselbe wie C# ist; Alle Objekte werden letztendlich von Object abgeleitet und mehrere Pfade zur selben Basisklasse sind für den Compiler mehrdeutig. Mehrdeutig == Schlecht, der Compiler erlaubt das nicht.

Stattdessen können Sie mehrfache Vererbung durch Delegierung simulieren. Ein Beispiel finden Sie unter this article.

+0

Eigentlich Sharing Objekt ist nicht mehrdeutig für den Compiler. Es wird nur mehrdeutig, wenn Methoden in verschiedenen Klassen definiert sind. Wenn also ein Zweig den Hashcode überschreibt und der andere nicht. In diesen Fällen muss der Programmierer eine Auswahl treffen. –

2

Mit java.lang.reflect.Proxy-Instanzen können Sie ein wenig schummeln (und ich betone etwas).

Damit können Sie nur zusätzliche Schnittstellen hinzufügen und ihre Aufrufe zur Laufzeit an eine andere Instanz delegieren.

Als jemand, Mentoren und Tutoren neue Entwickler würde ich entsetzt sein, wenn jemand zeigte mir Code, der das getan hat. Reflection ist eines dieser Tools, die man wirklich verstehen muss und die Java gut verstehen, bevor man hineinspringt. Ich persönlich habe das nur einmal gemacht, und es war etwas Code zu machen, den ich nicht kontrollieren konnte anderer Code, auf den ich keine Kontrolle hatte, erwartete (es war ein schneller Hack, also musste ich nicht zu viel Code schreiben und schreiben).

+0

Ja, das ist ein "netter Trick", aber das sollte niemand wirklich im Produktionscode verwenden! – Calum

+0

, aber um Proxy zu verwenden, benötigen Sie Schnittstellen. OP: "... ohne Verwendung der Schnittstelle ..." –

1

Sie müssen vorsichtig sein, um die Schnittstellenvererbung (im Wesentlichen die Vererbung eines Vertrags zur Bereitstellung bestimmter Einrichtungen) von der Implementierungsvererbung (Vererbung von Implementierungsmechanismen) zu unterscheiden.

Java bietet Vererbungsschnittstelle durch den Mechanismus implementiert und Sie können mehrere Interface-Vererbung haben.

Implementierung Vererbung ist die erweitert Mechanismus und Sie haben nur eine einzige Version davon. Haben Sie wirklich müssen mehrere Implementierungsvererbung? Ich wette, du tust es nicht, es ist randvoll mit unangenehmen Konsequenzen, außer du bist sowieso ein Eiffel-Programmierer.

1

Sie könnten wahrscheinlich „simulieren“, indem die Menge der übergeordneten Klassen explizit die Verwaltung und die Reflexion alle Superklassen für die Zielmethode zu suchen. Ich würde das nicht in der Produktion machen wollen, aber es könnte ein interessantes Spielzeugprogramm sein. Sie könnten wahrscheinlich eine Menge seltsamer Dinge tun, indem Sie Reflektionen nutzen, spontan Klassen erstellen und den Compiler programmatisch aufrufen.

0

Ich habe darüber ein wenig mehr nachgedacht und erkannt, dass dynamische Proxies zwar funktionieren (so funktioniert RMI (verwendet?)), Wenn Sie diese Art von Funktionalität wirklich wollen, sollten Sie besser aspektorientiert programmieren (AOP) mit etwas wie AspectJ (eclipse.org/aspectj).

Auf diese Weise können verschiedene Aspekte in eine Klasse zu bekommen, Sie Pseudo mixin Erbe, ohne die hideously fragile Erbe heirarchies geben.

Wie alle anderen darauf hingewiesen hat, wollen/Mehrfachvererbung benötigen im Allgemeinen bedeutet, dass Sie das Problem nicht aus der richtigen Perspektive nähern. Erinnern Sie sich an das GoF-Prinzip "Komposition vor Vererbung bevorzugen"!

4

Single Mehrere Vererbung wird nicht von Java unterstützt, stattdessen hat es Schnittstellen, die den gleichen Zweck erfüllen. Falls Sie darauf bestehen, Mehrfachvererbung zu verwenden, sollte dies in C++ geschehen.

0

durch innere Klassen verwenden, ist es das, was C++ manchmal auch bevorzugt: Inner Class Idiom.

-1

Ja kann man sagen, dass es ein Trick ist, und es ist sehr interessant, Sie nicht mehr Klassen zu einer einzigen Klasse erben kann, aber es ist möglich, mehrere Schnittstellen zu einer Klasse wie

public class parents implements first, second{ 

} 

aber nicht vergessen, zu implementieren, müssen Sie Methoden in Interfaces deklarieren.