2016-05-15 15 views
-1

Szenarien, in denen wir uns für die abstrakte Klasse entscheiden können und wo wir uns für das Überschreiben von Methoden entscheiden können. Lass mich das erklären. Ich habe eine Klasse A.Vorteile von abstrakten Methoden gegenüber Methodenüberschreibung

abstract class A { 
    abstract public void display(); 
} 

und im Normalfall kann ich diese Klasse als

class B extends A { 
    public void display() { 
     System.out.println("This is a bike"); 
    } 
} 

Das gleiche diese erweitere ich durch die Verwendung Methode überschrieben Merkmal, auch wenn die Methode der Klasse A tun könnte hat etwas.

Also meine Frage ist, wann sollte ich für die abstrakte Klasse gehen, wenn die gleiche Funktion kann ich durch Überschreiben der Methode erreichen.

+0

Ist nicht der Hauptvorteil von abstrakten Klassen, die Sie nicht instanziieren können (wie Schnittstellen), aber kann einen Basiskonstruktor bereitstellen und andere Klassen (wie Klassen) erweitern? – mezzodrinker

+0

Ich verstehe Ihre Frage nicht: Wenn Sie eine abstrakte Klasse mit einer abstrakten Methode haben, müssen Sie sie in der Unterklasse überschreiben. – hotzst

+0

Sie überschreiben hier bereits die Methode, weil Sie die Anzeigemethode überschreiben – Igorock

Antwort

0

Eine abstrakte Klasse ist eine Klasse mit mindestens einer abstrakten Methode. Dies ist eine Methode, die in dieser Klasse nicht implementiert ist, sondern von abgeleiteten Klassen implementiert werden muss.

Abstrakte Klassen sollten verwendet werden, um abstrakte Konzepte darzustellen. Sie können keine Objekte aus abstrakten Klassen erstellen, sie werden nur verwendet, um daraus konkrete Klassen abzuleiten.

Meiner Meinung nach sind abstrakte Klassen in den meisten Fällen nicht sinnvoll. Sie sollten stattdessen Schnittstellen verwenden.

+1

"Eine abstrakte Klasse ist eine Klasse, die mindestens eine abstrakte Methode hat. Das ist eine Methode, die nicht in dieser Klasse implementiert ist, sondern von abgeleiteten Klassen implementiert werden muss." Das ist nicht richtig. In C++ hättest du recht, aber [in Java kannst du eine Klassenzusammenfassung deklarieren, auch wenn sie keine abstrakten Methoden hat] (https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html). – Turing85

+0

@ Turing85: Du kannst, ja, aber würdest du? –

+1

[Natürlich] (http://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServlet.html). – Turing85

1

Der Hauptpunkt einer abstrakten Klasse/Methode ist die Bereitstellung eines Basistyps für die polymorphe Verwendung. Mit anderen Worten, Sie haben einen Basistyp A, den andere erweitern, um eine Operation zu ermöglichen. Sie interessieren sich nicht für die genaue Implementierung, aber Sie möchten, dass diese Operation verfügbar ist.

Ein oft zitiertes Beispiel ist eine Shape-Klasse:

abstract class Shape { 
    public abstract void draw(); 
} 
class Circle extends Shape { 
    int radius; 
    // Constructors, etc. 
    @Override 
    public void draw() { 
     System.out.println("Circle of radius " + radius); 
    } 
} 
class Square extends Shape { 
    int side; 
    // Constructors, etc. 
    @Override 
    public void draw() { 
     System.out.println("Square of side " + radius); 
    } 
} 

Klasse Form ist ein Weg, um jede Form bezieht. Sie wissen, dass es keine Instanzen der Klasse Shape geben kann, aber Sie können immer noch eine Shape[] oder eine List<Shape> haben. Auf diese Weise können Sie es wie folgt verwendet werden:

void drawAll(Iterable<? extends Shape> shapes) { 
    for (final Shape s : shapes) 
     s.draw(); 
} 

Wenn Sie nicht eine abstrakte Basisklasse Form haben, würden Sie nicht in der Lage sein, diese Methode zu schreiben; Sie würde man für eine Liste von Kreis-Objekte und ein anderer für eine Liste von Square Objekte schreiben - und selbst diese Lösung würde immer noch Sie dies nicht zulassen, dass tun:

List<Shape> ls = Arrays.asList(new Circle(7), new Square(5)); 
drawAll(ls); 
+0

Das ist nicht ganz richtig. All dies wäre möglich, auch wenn 'Shape' und seine' draw() 'Methode nicht abstrakt sind. Der Hauptvorteil ist, dass Sie jede Unterklasse von 'Shape' zwingen, entweder' draw() 'zu überschreiben oder selbst abstrakt zu sein. Sie können die Überschreibung der vorhandenen Methode nicht (einfach) erzwingen. – Turing85

+0

@ Turing85 in der Tat ... mein Punkt war der Vorteil von Shape über _not_ es (und damit nur eine Reihe von "nicht verwandten" Klassen mit einer Draw-Methode). Die "nächste Sache" zu "abstract" ohne tatsächlich das Schlüsselwort zu verwenden wäre, dass 'Shape.draw()' eine Ausnahme auslöst, also müsste jede nützliche Implementierung sie überschreiben. –

+0

Sie können die Methode 'draw' nicht ohne Körper deklarieren; Sie müssen es als abstrakt deklarieren: 'public abstract void draw();'. –

0

Das Wichtigste zuerst: Abstrakte Methoden eoncorporate zwingende . In diesem Sinne ist Ihre Frage etwas schlecht formuliert.

im Raum zu den Bären Jetzt: In Ihrem Beispiel haben Sie Beispiel Klassen A und B:

abstract class A { 
    abstract public void display(); 
} 

class B extend A { 
    @Override 
    public void display(){ 
     System.out.println("This is a bike"); 
    } 
} 

ich die @Override Anmerkung, den Begriff zu furhter erzwingen fügte hinzu, dass Abstraktion überwiegenden verwendet. Wenn display() in A wäre nicht absatract, hätten Sie keine (einfache) Möglichkeit zu erzwingen, dass jede Unterklasse von A eine Methode display() hat. Sie könnten natürlich display() innerhalb A implementieren.

In einigen Fällen ist dies jedoch möglicherweise nicht möglich, da Sie nicht genügend Informationen zum Schreiben der betreffenden Methode haben.Nehmen Sie zum Beispiel die get(int index) Methode einer Liste. Die Implementierung des Getters hängt stark von der Listenimplementierung ab (der Zugriff auf das 100. Element einer ArrayList funktioniert grundlegend anders als der Zugriff auf das 100. Element einer LinkedList). Aber Sie wissen sicher, dass jede Liste immer diese Methode haben sollte. So machen Sie diese Methode abstrakt .

Zusammenfassend: In einer perfekten Welt, in der jeder Programmierer Dokumente schreibt und liest, würden Sie wahrscheinlich keine abstrakten Methoden benötigen. Aber wir sind alle Menschen (d. H. Wir lesen nicht jede Zeile der Dokumentation und wir machen Fehler/vergessen Dinge) und deshalb ist es gut, einen Schutz gegen diese Fehler zu haben. Außerdem ist es kontraintuitiv, leere Methoden zu verwenden und zu erwarten, dass Benutzer sie überschreiben, damit Ihr Programm/Ihre Bibliothek funktioniert.


Nebenbei bemerkt: In Wirklichkeit List ist eine Schnittstelle, keine Klasse. Ich habe dieses Beispiel nur zu Demonstrationszwecken verwendet.

Verwandte Themen