5 Stimmen

Upcasting bei der Herstellung von Objekten

Angenommen, Sie haben eine Shape Basisklasse und verschiedene abgeleitete Typen: Circle , usw.

Gibt es jemals einen Grund zu upcast genau dort, wenn ein neues Objekt zu machen, durch das Schreiben dieser:

Shape s = new Circle();

stattdessen:

Circle s = new Circle();

und sind die s Gegenstand dieser beiden Aussagen in irgendeiner Weise voneinander unterscheiden?

3voto

WhiteFang34 Punkte 69056

Diese beiden Anweisungen erzeugen für die JVM das gleiche Objekt. Es ist nicht ungewöhnlich, anzugeben, dass Sie das Objekt nur für die Basisklasse oder Schnittstelle verwenden wollen. Dies ist z.B. üblich:

List<String> list = new ArrayList<String>();

Obwohl dies im Allgemeinen keine gute Idee ist, können Sie die Shape zurück in eine Circle wenn Sie sicher wissen, dass es eine ist, z. B. mit Shape s können Sie es wieder auf eine Circle c mit:

if (s instanceof Circle) {
    Circle c = (Circle) s;
    // handle Circle case
}

3voto

brent777 Punkte 3329

Sie können argumentieren, dass Ihr erstes Beispiel (d. h. Shape s = new Circle(); ) kann die gleichen Vorteile haben wie "Coding to the interface", auch wenn Shape eine abstrakte oder sogar eine konkrete Basisklasse sein könnte. Wenn Sie zum Beispiel nur die Methoden von Shape verwenden und nicht die von Circle, dann können Sie die Implementierung, die Sie verwenden, ganz einfach in Square ändern, indem Sie nur eine Zeile Code ändern, z. B. Shape s = new Square(); .

Die Objekte sind in beiden Beispielen die gleichen, der Grund, warum die erste Option als besser angesehen werden kann, ist eher eine Frage des Stils. Die Kodierung nach Schnittstellen kann eine Codebasis leichter erweiterbar und änderbar machen.

2voto

Heisenbug Punkte 38304

Die instanziierten Objekte sind genau dieselben.

Die Folgen eines Upcasting sind:

  1. Verallgemeinerung beim Speichern: alle Objekte verschiedener spezialisierter Typen können als dieselbe Schnittstelle bezeichnet und zusammen in einer Datenstruktur gespeichert werden. (Wie von @WhiteFang34 aufgezeigt: Liste <Form>)
  2. Verallgemeinerung beim Zugriff auf die Objektmethode: die Client-Klasse kann die Shape-Methode aufrufen, ohne den tatsächlichen Typ zu kennen (typischerweise kann man eine Fabrik verwenden, um ein Objekt zu erzeugen, das die allgemeine Schnittstelle Shape zurückgibt, so dass die Client-Klasse den tatsächlichen Typ der Objekte nicht kennt, sondern nur die Schnittstellenmethoden von Shape offengelegt werden)

1voto

CodeClimber Punkte 4418

Um Ihre Frage zu beantworten: Die beiden Objekte sind genau gleich. Beide Verweise können auf dasselbe Objekt verweisen:

Circle c = new Circle();
Shape s = c;

Die Kodierung in Schnittstellen ermöglicht es Ihnen, die Implementierungsklasse mit minimalen Auswirkungen auf Ihren Code zu ändern. Angenommen, Sie haben Folgendes:

Set<String> names = new HashSet<String>();         // using Set reference not HashSet
names.add("Frank");
names.add("John");
names.add("Larry");

for(String name: names) {
    System.out.println(name + " is in the team");
}

Nun ändern sich Ihre Anforderungen und Sie möchten, dass die Namen in alphabetischer Reihenfolge ausgegeben werden, d.h. Sie verwenden HashSet statt TreeSet. Da Sie sich an die Schnittstelle gehalten und keine spezifischen Methoden der Klasse HashSet verwendet haben, müssen Sie nur eine Zeile ändern:

Set<String> names = new TreeSet<String>();   // the only line of code that changes
names.add("Frank");
names.add("John");
names.add("Larry");

for(String name: names) {
    System.out.println(name + " is in the team");
}

Schnittstellen ermöglichen Ihnen auch die Verwendung von Dependency Injection. Damit können Sie Klassen verwenden, die zum Zeitpunkt der Erstellung Ihres Codes möglicherweise noch gar nicht existieren.

http://en.wikipedia.org/wiki/Dependency_injection

0voto

DarkDust Punkte 87647

Nein, die Objekte selbst sind nicht unterschiedlich. Nur das, was der Compiler zu sehen glaubt, ist anders (z. B. welche Methoden verfügbar sind).

Ein Grund für einen solchen Cast ist es, auszudrücken, wie Sie das Objekt behandeln möchten (so dass Sie stattdessen einfach eine andere abgeleitete Klasse einfügen können).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X