2010-06-30 25 views
6

Kann jemand Nachteil der Vererbung in Java erklärenNachteile der Vererbung in Java

+0

nicht java perse, wenn jemand die Nachteile der Vererbung erklärt .. das ist eine gute Lektüre. :) –

+3

Können Sie ... den Umfang Ihrer Frage ein wenig enthalten? Gibt es bestimmte Probleme, um die Sie sich Sorgen machen? Zum Beispiel, Single-vs Multiple-Vererbung oder Klasse vs prototypische Vererbung, oder ... (Oder ist das Hausaufgaben?) –

+0

Nachteil im Vergleich zu Vererbung in anderen Sprachen, oder Nachteile der Vererbung im Vergleich zu Zusammensetzung zum Beispiel? –

Antwort

9

Sie wahrscheinlich lesen möchten:

Effective Java ™, Second Edition Von: Joshua Bloch

Kapitel 4. Klassen und Schnittstellen

Artikel 16: Favor Komposition der Vererbung

Punkt 17: Entwurf und doc stätigen für die Vererbung oder sonst verbieten es

Artikel 18: Bevorzugen Schnittstellen zu abstrakten Klassen

5

Nehmen Sie eine Beute bei Allen Holub den Artikel in Javaworld Why extends is evil berechtigt. Er diskutiert Dinge wie die enge Kopplung und das fragile base class Problem.

+0

Der Artikel schont nicht die Vererbung an sich und erweitert nur die konkreten Basisklassen. –

1

Wir bevorzugen Komposition über Vererbung, denn wenn wir (besonders) hinzufügen oder Funktionalität durch Unterklassen ändern, koppeln wir diese neue Funktionalität an die Klasse - überall dort, wo wir die neue Funktionalität brauchen, brauchen wir diese Klasse. Das erstreckt sich sogar auf weitere Unterklassen - und mit dem Java-Modell mit einer einzigen Vererbung gibt es, wenn wir zwei neue Bits an Funktionalität in einer anderen Klasse haben, keine (einfache) Möglichkeit, beide Bits einzufügen, wenn jede in einer separaten Unterklasse von ist der ursprüngliche Vorfahre. Wenn wir die Funktionalität über Komposition erweitern, kann jede Klasse - egal ob in oder aus unserer bestehenden Hierarchie - im Vergleich dazu die einfache Klasse mit der neuen Funktion einbeziehen. Es ist einfacher, sauberer, wiederverwendbarer und einfacher zu lesen.

Vererbung hat ihren Platz, aber es ist nicht das richtige Werkzeug für viele, viele Jobs.

3

Sofern Ihre Klasse nicht für die Vererbung ausgelegt ist, sollte sie endgültig sein. Sie müssen sehr vorsichtig sein, um sicherzustellen, dass Sie verstehen, wie Methoden, die in einer Unterklasse überschrieben werden, die nicht für die Vererbungsfunktion entworfen wurde, um zu verstehen, wie sie geändert werden.

Ein konkretes Beispiel:

Betrachten Sie eine Klasse, die eine Liste von Namen verwaltet ...

public class MyNameManager { 
    private List<String> numbers = new LinkedList<String>(); 

    public void add(String value) { 
    numbers.add(value); 
    } 

    public void addAll(Collection<String> values) { 
    for(String value : values) { 
     add(value); 
    } 
    } 

    public void remove(String value) { //... } 

    //... 
} 

Jetzt sagen Sie, eine neue Unterklasse erstellen möchten, die auch die Gesamtzahl zählt Manchmal wird ein Name zur Liste hinzugefügt, so:

public class MyCountingNameManager extends MyNameManager { 
    private int count = 0; 

    @Override 
    protected void addAll(Collection<String> values) { 
    count += values.size(); 
    super.addAll(values); 
    } 

    @Override 
    protected void add(String value) { 
    count += 1; 
    super.add(value); 
    } 
} 

Scheint ziemlich einfach, nein? Aber betrachten Sie das Ergebnis der folgenden:

MyCountingNameManager m = new MyCountingNameManager(); 
m.add("bob"); 
m.add("Sally"); 

Die Anzahl ist jetzt 2, und alles ist gut. Aber wenn wir folgendes tun waren:

List<String> family = new List<String>(); 
family.add("mom"); 
family.add("dad"); 
family.add("brother"); 

MyCountingNameManager m = new MyCountingNameManager(); 
m.add(family); 

Der Graf ist jetzt 6, nicht die 3 würden Sie vermutlich erwarten. Dies liegt daran, dass der Aufruf an addAll die Größe der Sammlung von Werten (die 3 ist) zur Zählung hinzufügt und dann die super.addAll-Methode aufruft, um die tatsächliche Verarbeitung durchzuführen.super.addAll iteriert die Collection und ruft für jeden Wert die Methode add auf. Aber da wir in einem MyCountingNameManager und nicht ein MyNameManager arbeiten, wird die überschriebene add Methode in der Unterklasse jedes Mal aufgerufen. Die Methode MyCountingNameManager.add, die ausgeführt wird, erhöht auch die Anzahl! Das Ergebnis ist, dass jeder Name doppelt gezählt wird!

Ich glaube, dieses Beispiel stammt aus Effective Java. Sie sollten auf jeden Fall eine Kopie finden und die in Vieles Antwort aufgelisteten Elemente lesen, um ein tieferes Verständnis einiger Fälle zu erhalten, in denen Vererbung schlecht passt.