Schlüsselworte Dynamische Polymorhpie

masterholdy

Mitglied
Hi Leute,

könnte mir jemand sagen, wenn es 2 Klassen gibt
A - machwas()
B erbt von A - machwas()

hat wo der Unterschied zwischen
A a = new A(); und A a = new B(); ist?

Wenn ich es richtig verstanden habe dann ist doch bei A a = new B();
a immernoch ein A somit sind die beiden doch equivalent oder? Falls ja wo ist der Sinn hinter dieser Schreibweise?

MFG
 

mrBrown

Super-Moderator
Mitarbeiter
Bei zweiter Variante ist a ein B, ruft man darauf zB #machwas auf, wird die Implementierung von B ausgeführt, nicht von A
 

Viktim

Bekanntes Mitglied
Der Sinn kommt erst, wenn du noch eine Klasse C hast, die auch von A erbt ;)
Dann kannst du deiner Methode sagen, sie bekommt ein A-Objekt übergeben, ob es sich dabei um Klasse B oder C handelt ist der Methode dann egal ;)
 

mrBrown

Super-Moderator
Mitarbeiter
Was in 99% der Fälle zu totalem Chaos führt :)

Wie sollte sowas zu totalem Chaos führen? Solange die Methode das tut, was sie soll, ist doch alles passend. Interfaces zu benutzen führt ja auch nicht plötzlich zu totalem Chaos...

Der Sinn kommt erst, wenn du noch eine Klasse C hast, die auch von A erbt ;)
Dann kannst du deiner Methode sagen, sie bekommt ein A-Objekt übergeben, ob es sich dabei um Klasse B oder C handelt ist der Methode dann egal ;)
Hier gibt es schon zwei Implementation - A und B, also kein C nötig ;)

also würde sich a wie ein B verhalten ist jedoch auf die methoden die A hat beschränkt?
Ja. Zumindest lassen sich nur diese direkt aufrufen.

wie sieht es mit obj. variablen aus?
Was?
 

mrBrown

Super-Moderator
Mitarbeiter
Was für einen Grund gibt es dann a als A zu deklarieren und nicht gleich als B?
Um statt B auch A oder C benutzen zu können?

wenn A und B jetzt beide eine objektvariable int i
haben greife ich dann mit A a = new B(); auf das i von a oder b zu=?


mit a.i dürfte das afaik das A von i sein, in Methoden von B kannst du das mit this und super angeben, in A nur das i von A. Man sollte aber gleich lautende Variablen beim Erben vermeiden ;)
 

mrBrown

Super-Moderator
Mitarbeiter
Nein warum auch, ich kann aber trotzdem alle Methoden von A benutzen und in sofern ist das gar nicht nötig.

Würdest du auch empfehlen, nie wieder Interfaces zu benutzen? Wenn ich da stattdessen eine Implementation benutze, kann ich schließlich auch alle Methoden des Interfaces benutzen...

Abgesehen davon kann ich eben nicht die Methoden von A oder C benutzen, B kann die schließlich anders implementiert haben.
 

Thallius

Top Contributor
Ich glaube wir reden aneinander vorbei.

Nehmen wir doch mal ein konkretes Beispiel:

Child erbt von Person

Person p = new Person();
Child c = new Child();

Welchen Sinn könnte nun eine definition von

Person c = new Child();

haben? Nenne mir bitte einen konkreten Anwendungsfall.
 

mrBrown

Super-Moderator
Mitarbeiter
Das man nicht an new Child() gebunden ist, steht doch oben^^

Aber um mal zu deiner Ausgangsaussage zurückzukehren: Person c = new Child(); verursacht also totales Chaos?
 

Harry Kane

Top Contributor
Die Polymorphie-Diskussion gabs doch schon mal hier.
Meine 2 cents:
- Wenn c nur eine lokale oder eine private Instanzvariable ohne setter ist, ist die Deklaration als Child vollkommen ok. c als Person zu deklarieren, wenn klar ist, das ein Child gebraucht wird, ist Unfug.
- Wenn c über einen setter gesetzt werden kann, und man dem Aufrufer der Methode die Möglichkeit geben möchte, neben Child auch weitere Unterklassen von Person zu verwenden, muss c natürlich als Person deklariert werden.
 

Meniskusschaden

Top Contributor
c als Person zu deklarieren, wenn klar ist, das ein Child gebraucht wird, ist Unfug.
Warum sollte denn klar sein, dass ein Child benötigt wird? Doch nur, falls das Child auf irgendeine Weise speziell ist, so dass Person nicht geeignet ist, etwa weil eine Child-Methode benötigt wird. Dann würde es mit Person ja ohnehin nicht funktionieren. Falls Person jedoch auch geeignet sein sollte, ergibt es doch keinen Sinn, sich auf ein Child festzulegen. Wundere mich etwas über die Diskussion, weil ich bisher dachte, das Prinzip "So allgemein wie möglich, so speziell wie nötig" sei völlig unstrittig.
 

X5-599

Top Contributor
Ich erinnerer mich an diese Diskussion. Achtung! Alles folgende ist meine persönliche Meinung: Wenn man "nichts" mit den Objekten macht, würde ich sagen dass es persönliche Präferenz ist. Person p = new Child() vs Child c = new Child(). ABER:
Da man sich ja meist in komplexeren Sytemen aufhält sieht das ganze wieder anders aus. Hier mal ein konkretes Beispiel: Familienstammbaum erstellen.
Code:
public void init()
{
  StammBaum s = new StammBaum();
  Child c = new Child();
  Father f = new Father();
  Mother m = new Mother();

  s.addChild(c);
  s.addFather(f);
  s.addMother(m);
}

Kann man sicherlich so machen. Macht aber nur Sinn wenn die verschiedenen addXXX Methoden unterschiedliches Verhalten an den Tag legen (oder wenn es drei separate Listen für die Instanzen gibt). Wenn sie nur Instanzen hinzufügen (die nicht getrennt abgelegt werden sollen) kann eine allgemeine addPerson(Person) Methode mehr Sinn machen. Ich sage "kann" weil es immer darauf ankommt. Worauf? Ich würde sagen: Darauf wieviele Gemeinsamkeiten die einzelnen Klassen haben. Polimorphie erspart einem ja zb Code Dopplung.
Sie gibt einem aber auch die Möglichkeit gemeinsames Verhalten an die jeweilige Klasse anzupassen. Sie gar komplett anders zu handhaben.

TL;DR
Kommt in einem Projekt Polimorphie vor, wird es früher oder später die Notwendigkeit von Methoden geben, die mit der Allgemein gültigsten Klasse arbeiten werden. Daher bietet es sich an mit dieser zu arbeiten (zumindest da, wo keine "spezialisierten" Methoden etc gebraucht werden)

Zum Schluss: Ich bin außerdem der Meinung, dass "Auf Biegen und Brechen" Polimorphie einzusetzen genauso wenig die Lösung ist wie komplett darauf zu verzichten. Softwarearchitektur heisst auch zu erörtern welches "Werkzeug" oder Pattern wann einzusetzen ist.
 
Zuletzt bearbeitet:

Harry Kane

Top Contributor
c als Person zu deklarieren, wenn klar ist, das ein Child gebraucht wird, ist Unfug.
Warum ist es denn Unfug?
Ehrlich, die Rückfrage verstehe ich nicht.
Wenn ich ein Child brauche (z. B. weil ich eine Child-Methode aufrufen will oder das Child an eine Methode übergeben will, die einen Child-Parameter erwartet), dann ist es Unfug, die Variable c, die ja als Child initialisiert wurde und demnach ein Child ist, als Person zu deklarieren, weil ich dann bei den oben geschilderten use cases (Methodenaufruf oder Übergabe als Parameter) immer casten müsste. Der cast des als Person deklarierten Objekts auf Child wird zwar funktionieren, aber warum sollte man sich das antun?
Warum sollte denn klar sein, dass ein Child benötigt wird?
Tja, diese Frage kann nur anhand des weiteren Programmkontextes beantwortet werden.
Wenn diese Bedingung
Wenn c nur eine lokale oder eine private Instanzvariable ohne setter ist, ...
erfüllt ist, halte ich die Deklaration
Person c = new Child();
nur dann für sinnvoll, wenn Person nicht instanziiert werden kann, weil Person entweder eine abstrakte Klasse oder ein interface ist. Falls beides NICHT gegeben ist, gibt es zwei Fälle:
a) ich will c als Child verwenden (s. o.). Dann ist es Unfug, es als Person zu deklarieren.
b) ich will c als Person verwenden. Dann stellt sich die Frage, warum nicht direkt eine Instanz von Person erzeugt wird.
 

mrBrown

Super-Moderator
Mitarbeiter
c als Child benutzen lass ich mal weg, da ist es klar, dass man es es Child deklariert.

b) ich will c als Person verwenden. Dann stellt sich die Frage, warum nicht direkt eine Instanz von Person erzeugt wird.

Weil ich die Implementierung von Child möchte?
Warum sollte ich mich dann, wenn ich nur irgendeine Person haben will, und es für den restlichen Code egal ist, direkt auf eine bestimmt einschränken?

Ob man es lieber allgemein oder spezieller deklariert, mag persönliche Differenz sein. Aber den allgemeinen Fall als Unfug zu bezeichnen, halte ich für Unfug ;)
 

Meniskusschaden

Top Contributor
Wenn ich ein Child brauche (z. B. weil ich eine Child-Methode aufrufen will oder das Child an eine Methode übergeben will, die einen Child-Parameter erwartet), dann ist es Unfug, die Variable c, die ja als Child initialisiert wurde und demnach ein Child ist, als Person zu deklarieren, weil ich dann bei den oben geschilderten use cases (Methodenaufruf oder Übergabe als Parameter) immer casten müsste.
Natürlich ist es dann Unfug. Den Standpunkt vertritt hier aber auch niemand. Es ging um den Fall, dass A und B über die Methode machwas() verfügen, allgemein gesprochen also darum, ob man gegen interfaces programmieren soll. Das hat mit deinem Beispiel nichts zu tun.

Warum sollte denn klar sein, dass ein Child benötigt wird?
Tja, diese Frage kann nur anhand des weiteren Programmkontextes beantwortet werden.
Wenn diese Bedingung
Nein, man kann auch versuchen, das allgemein unabhängig vom konkreten Kontext zu definieren. Habe ich oben ja auch versucht und dein Beispiel passt genau in diese Definition, denn du forderst etwas Spezifisches vom Child, das Person nicht leisten kann. Wenn nichts Spezifisches gefordert wird, sollte man sich auch nicht festlegen.
 

Flown

Administrator
Mitarbeiter
Endlich habe ich die Muße gefunden und diesen Thread mal überflogen.
Also ihr redet aneinander vorbei. Was gefragt wurde: dynamic dispatching.
Was ihr zu diskutieren versucht ist z.B.: Ist es besser ArrayList<T> list = new ArrayList<>(); zu verwenden oder List<T> list = new ArrayList<>();.

Bei der Grundfrage kann man sagen, dass das der einzige Sinn von Polymorphie ist.
Bei der zweiten Frage: Es kommt immer darauf an welche Funktionalität ich gerade benötige. Falls ich konkrete Methoden einer Klasse brauche, dann nehme ich auch die konkrete Klasse.
 

X5-599

Top Contributor
Also, wenn wir hier nur vom simplen Objekte Erzeugen reden und sowas wie Übergabe Parameter und Generische Typen in zB Listen außer Acht lassen, würde ich sagen:
Es ist eine persönliche Präferenz wie man es nun schreibt.

zB schreibe ich immer: JFrame frame = new JFrame(); Auch in Fällen wo ich dessen spezifische Methoden wie "setDefaultCloseOperation" nicht brauche. Klar könnte ich auch Window frame = new JFrame(); schreiben... mach' ich aber nicht.
 

Harry Kane

Top Contributor
Weil ich die Implementierung von Child möchte?
Warum sollte ich mich dann, wenn ich nur irgendeine Person haben will, und es für den restlichen Code egal ist, direkt auf eine bestimmt einschränken?
Wenn ich das Verhalten von Child haben möchte, und dieses ja auch durch die Instanziierung erreiche/erzwinge, würde ich auf jeden Fall dafür plädieren, dass das auch an der Deklaration erkennbar sein sollte.
Der einzige Vorteil, den ich durch die Deklaration von c als Person erkennen kann, ist der, das nur die Zeile wo c instanziiert wird, geändert werden muss, und nicht auch die Zeile wo es deklariert wird, wenn ein anderer Typ von Person gewünscht wird.
ArrayList<T> list = new ArrayList<>();
List<T> list = new ArrayList<>();
Hier habe ich bisher stets die erste Variante verwendet. Zum einen ist jetzt auf Anhieb im Kopf der Klasse erkennbar, welche Implementierung konkret gewählt ist, und ich muss nicht den Ort der Initialisierung suchen. Ausserdem kann der Import von java.util.List gespart werden.

Gibt es zum Punkt "Deklaration von lokalen Variablen oder von Instanzvariablen, die keinerlei Relevanz für die öffentliche Schnittstelle einer Klasse haben" eigentlich offizielle Empfehlungen?
 

mrBrown

Super-Moderator
Mitarbeiter
Wenn ich das Verhalten von Child haben möchte, und dieses ja auch durch die Instanziierung erreiche/erzwinge, würde ich auf jeden Fall dafür plädieren, dass das auch an der Deklaration erkennbar sein sollte.
Hier habe ich bisher stets die erste Variante verwendet. Zum einen ist jetzt auf Anhieb im Kopf der Klasse erkennbar, welche Implementierung konkret gewählt ist, und ich muss nicht den Ort der Initialisierung suchen. Ausserdem kann der Import von java.util.List gespart werden.

In den meisten Fällen ist es (zumindest mir) nicht relevant, auf welche Implementation man arbeitet. Wenn es wirklich relevant sein sollte, dann hauptsächlich, weil man spezielle Methoden braucht, und dann kommt man ehh nicht ums genaue Deklarieren drum rum.

Imports sind da aber wirklich kein Grund (und wenn man statt import java.util.ArrayList java.util.* nutzt, spart man sogar ein paar Zeichen ;)).
 

Flown

Administrator
Mitarbeiter
Hier habe ich bisher stets die erste Variante verwendet. Zum einen ist jetzt auf Anhieb im Kopf der Klasse erkennbar, welche Implementierung konkret gewählt ist, und ich muss nicht den Ort der Initialisierung suchen. Ausserdem kann der Import von java.util.List gespart werden.
Erklär doch mal welchen Vorteil dir das bringt? Als Frameworkentwickler musst du immer Implementierungsfrei arbeiten und das geht nur mit Interfaces. Denn wenn du einmal was auswechseln möchtest musst du es an allen! Codestellen dann ändern und nicht nur bei der "anscheinend" schwer zu findenden Stelle bei der Initialisierung.
 

Flown

Administrator
Mitarbeiter
Ist in diesem Fall egal, was mal "lokal" war kann schnell öffentlich werden und dann möchte ich bei dem Refactoring aber nicht dabei sein!
 

Harry Kane

Top Contributor
was mal "lokal" war kann schnell öffentlich werden
Was? Ich schliesse jetzt mal aus, dass du damit meinst, eine private Instanzvariable könnte schnell mal public werden.
Wenn eine private Variable zum Bestandteil der öffentlichen API wird, dann doch mit Sicherheit nur über setter und getter. Dann sollten die Rückgabewerte bzw. Methodenparameter in der Tat keine unnötig spezielle Deklaration haben. Um auf das Beispiel mit der privaten ArrayList zurückzukommen: der Rückgabewert eines getters sollte in > 99% aller Fälle nicht als ArrayList deklariert werden.

[edit] Kann man die letzten beiträge vielleicht in einen neuen thread verschieben?
 

Flown

Administrator
Mitarbeiter
Wenn eine private Variable zum Bestandteil der öffentlichen API wird, dann doch mit Sicherheit nur über setter und getter. Dann sollten die Rückgabewerte bzw. Methodenparameter in der Tat keine unnötig spezielle Deklaration haben
War gemeint und bilden einen Konsens.

Trotzdem sollte man in der internen API so allgemein/abstrakt wie möglich bleiben. Denn Code entwickelt sich weiter und dann hat man den Salat, aber eben später.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
ohneInformatik; Dynamische Zinsen. Wo liegt der Fehler? Java Basics - Anfänger-Themen 4
A Erste Schritte Dynamische Stempel im PDF Exchange programmieren Java Basics - Anfänger-Themen 0
B Fibonacci Zahlen dynamische Programmierung Java Basics - Anfänger-Themen 7
M Fehlendes Verständnis für dynamische Bindung und Vererbung Java Basics - Anfänger-Themen 13
L Dynamische Anzahl an Arrays mit verschiedenen Namen erzeugen Java Basics - Anfänger-Themen 6
L Dynamische Bindung Java Basics - Anfänger-Themen 3
W OOP Definition / Abgrenzung dynamische Bindung Java Basics - Anfänger-Themen 11
J Dynamische Datenstrukturen Java Basics - Anfänger-Themen 0
L Variablen Dynamische Variablenname Java Basics - Anfänger-Themen 9
L Dynamische Programmierung Java Basics - Anfänger-Themen 0
J OOP Dynamische Objektnamen Java Basics - Anfänger-Themen 6
Ste3et_C0st Dynamische While/For Schleife Java Basics - Anfänger-Themen 7
F Erste Schritte Dynamische Variablen Java Basics - Anfänger-Themen 15
M Dynamische Methode aus anderer Klasse aufrufen Java Basics - Anfänger-Themen 11
S Dynamische Variable ist? Java Basics - Anfänger-Themen 11
S Verwirrung - Dynamische Bindung greift nicht Java Basics - Anfänger-Themen 2
C Dynamische Referenz & abstrakte Klassen Java Basics - Anfänger-Themen 3
P Klassen statische oder dynamische(?) Klasse Java Basics - Anfänger-Themen 3
J Dynamische Liste durchsuchen + anpassen Java Basics - Anfänger-Themen 3
A Schlüsselworte dynamische Stringteilung Java Basics - Anfänger-Themen 4
C Dynamische (AJAX) Inhalte einer Webseite mittels Java auslesen Java Basics - Anfänger-Themen 2
W Übungsaufgabe:Dynamische Datenstrukturen Java Basics - Anfänger-Themen 10
B dynamische erzeugung eines Objektes Java Basics - Anfänger-Themen 21
L Dynamische Objektgenerierung Java Basics - Anfänger-Themen 4
K Dynamische Bindungsregel Java Basics - Anfänger-Themen 2
B dynamische/statische Typen Java Basics - Anfänger-Themen 2
C dynamische JTextFields durchlaufen Java Basics - Anfänger-Themen 5
H Dynamische Bindung mit Interfaces und LinkedList Java Basics - Anfänger-Themen 7
N OOP Dynamische Objekte und nach Parametern durchsuchen Java Basics - Anfänger-Themen 4
M dynamische JPanels/Component Java Basics - Anfänger-Themen 3
X dynamische Listen Java Basics - Anfänger-Themen 2
A Schnelle, dynamische, geordnete Datenstruktur? Java Basics - Anfänger-Themen 11
M Dynamische JButtons mit ActionListener Java Basics - Anfänger-Themen 7
Y Kleine Verständnisfrage zum Thema dynamische Polymorphie Java Basics - Anfänger-Themen 3
C Dynamische Matrizen Java Basics - Anfänger-Themen 4
0 Dynamische Datenstruktur ohne Duplikate und mit direkter Elementauswahl Java Basics - Anfänger-Themen 3
N Vererbung/Dynamische Bindungen Java Basics - Anfänger-Themen 15
W Dynamische Bindung Java Basics - Anfänger-Themen 3
P jsp tags und scriplets mischen dynamische werte an jsp tag Java Basics - Anfänger-Themen 2
S Dynamische Tabelle Java Basics - Anfänger-Themen 2
P Suche Ersatz für dynamische arrays Java Basics - Anfänger-Themen 2
T Dynamische Reaktionen Java Basics - Anfänger-Themen 29
P Dynamische Bindung Java Basics - Anfänger-Themen 8
F Dynamische Speicheranpassung und exe Java Basics - Anfänger-Themen 9
D Dynamische Objektnamen / Variablen als Objektnamen verwenden Java Basics - Anfänger-Themen 3
J dynamische Auswahl einer überladenen Methode Java Basics - Anfänger-Themen 5
C JTable und dynamische Speicherung Java Basics - Anfänger-Themen 2
M Dynamische Wertsetzung von Variablen durch Eingaben Java Basics - Anfänger-Themen 9
J Dynamische Größenveränderung der Komponenten verhindern Java Basics - Anfänger-Themen 8
C Dynamische Operatoren! Java Basics - Anfänger-Themen 5
R dynamische Variablennamen Java Basics - Anfänger-Themen 3
M dynamische, assziative Arrays Java Basics - Anfänger-Themen 2
I dynamische mehrdimensionales Array Java Basics - Anfänger-Themen 8
H Unterschied statischer/dynamische Typ einer Variablen Java Basics - Anfänger-Themen 2
H statische,dynamische Bindung Java Basics - Anfänger-Themen 4
0 Dynamische Speicherverwaltung Java Basics - Anfänger-Themen 4
B Dynamische If Anweisung Java Basics - Anfänger-Themen 13
B Dynamische Variable Java Basics - Anfänger-Themen 12
C Dynamische Arraygröße Java Basics - Anfänger-Themen 2
M dynamische tabellen Java Basics - Anfänger-Themen 2
G Java dynamische Arrays?? Java Basics - Anfänger-Themen 2

Ähnliche Java Themen

Neue Themen


Oben