Konstruktorenverkettung

Status
Nicht offen für weitere Antworten.
A

Anfaenger

Gast
Hi Leute, ich habe folgendes Problem, was ich mir nicht erklären kann.

Es geht und die Ausgabe des folgendes Progs. Die Ausgabe des Progs lautet für die 3 Aufrufe in der main():

b, 9, D, 10, A, (C), 0, C, 1, B, 9

A,(1)

A,(17)

Die eingeklammerten Ausdrücke kann ich nicht nachvollziehen. Kurze Situationsschilderung am Beispiel des ersten Aufrufs [also das (C)]

"Klasse A" ist Superklasse von "Klasse C" und "Klasse C" überschreibt Operation print() von "Klasse A"

=> bei der Instanziierung eines C-Objektes (= Unterklasse), also bei Aufruf des Konstruktors der Unterklasse wird automatisch der Konstruktor der Oberklasse (=Klasse A) aufgerufen, welcher print() aufruft.

Jezt meine Frage: Da print() sowohl in "Basisklasse A" UND in "Unterklasse C" vorkommt müßte doch eben vom Konstruktor der Basisklasse die eigene print()-Operation aufgerufen werden und als Ausgabe >A< , anstelle von (C) ausgegeben werden.
Da allerdings (C) ausgegeben wird, folgt daraus, dass der Basisklassen-Konstruktor die print()-Operation der Unterklasse aufruft. Das ist doch meines erachtens nicht möglich, da

1) eine Oberklasse nicht auf Elemente ihrer Unterklasse zugreifen kann. Das ginge nur mit Referenzen (speziell mit einem Up-Cast => Zuweisung einer Referenz einer Unterklasse an eine Referenzvariable ihrer Oberklasse)

2) Da wird uns in Konstruktoraufrufen befinden, wurden noch keine Referenzen übergeben und somit, kann logischerweise die Oberklasse nicht auf die print()-Operation ihrer Unterklasse zugreifen. Sie tut es aber doch.

=> mögliche und wahrscheinliche Erklärung: VM bindet dynamisch, richtig? Aber wie kann dynamisch gebunden werden, wenn noch keine Referenzen übergeben und zugewiesen wurden: Referenzen auf ihre Objekte werden erst NACH der Ausführung der Konstruktoren erlangt und zugewiesen.

Vielleicht kann mir jemand diesen Sachverhalt im Detail erklären.

Danke ;-)

----------------------------------------------------------------------
Code:
// Klasse A
public class A
{
	static int wert = 0;
	
	A(){
		print();
		wert++;
	}
	
	void print(){
		System.out.println("A");
		System.out.println(wert);
	}
	
	void print(int z){
		System.out.println("A");
		System.out.println(wert+z);
	}
}

//Klasse B
class B
{
	int wert = 8;
	
	B(){
		wert++;
	}
	
	void print(){
		System.out.println("B");
		System.out.println(wert);
	}
}

// Klasse C
class C extends A
{
	D einD;
	
	C(){
		print();
		einD = new D();
		}
		
	void print(){
		System.out.println("C");
		System.out.println(wert);
		}
}	

//Klasse D
class D extends B
{
	D(){
		super.print();
		wert++;
	}
	
	void print(){
		System.out.println("D");
		System.out.println(wert);
	}
}

//Klasse E
class E extends D
{
	C einC;
	
	E(){
		print();
		einC = new C();
	}
}

class Haupt
{
	public static void main(String args[]){
		E dasE = new E();
		A dasA = new A();
		dasA.print(15);
		System.out.println("\n--------------------------\n");
		C dasC = new C();
	}
}
 

Slava

Bekanntes Mitglied
Anfaenger hat gesagt.:
Die Ausgabe des Progs lautet für die 3 Aufrufe in der main():

b, 9, D, 10, A, (C), 0, C, 1, B, 9

A,(1)

A,(17)

wäre es möglich main methode zu zeigen und richtige Programmausgabe?
 
B

Beni

Gast
1) eine Oberklasse nicht auf Elemente ihrer Unterklasse zugreifen kann. Das ginge nur mit Referenzen (speziell mit einem Up-Cast => Zuweisung einer Referenz einer Unterklasse an eine Referenzvariable ihrer Oberklasse)
Das ist eben nicht ganz richtig. Auf überschriebene Methoden einer Unterklasse hat die Oberklasse zugriff (was ja der Sinn von OOP ist, deshalb nennt man den Vorgang auch "überschreiben"), allerdings "weiss" die Oberklasse das nicht. Ob das im Konstruktor oder in einer Methode geschieht macht (fast) keinen Unterschied.

2) Da wird uns in Konstruktoraufrufen befinden, wurden noch keine Referenzen übergeben und somit, kann logischerweise die Oberklasse nicht auf die print()-Operation ihrer Unterklasse zugreifen. Sie tut es aber doch.
Offenbar hat deine Logik einen Fehler, denn sie kann mit einem Gegenbeispiel widerlegt werden. Vielleicht ist auch die Programmiersprache nicht logisch, was ich aber für sehr unlogisch halten würde.
Vielleicht solltest Du auch einfach Tatsachen akzeptieren: es ist so, selbst wenn Du es nicht glaubst.

Was nicht funktionien wird:
Wenn eine Methode der Unterklasse, die im Konstrktor der Oberklasse aufgerufen wird, "this" verwenden will. Denn this ist (in der Unterklasse) ist noch null, während der Konstruktor der Oberklasse ausgeführt wird.


Der Aufbau der Klasse wird geladen, bevor der Konstruktor überhaupt aufgerufen ist. Die Zuweisung (und evtl. Initialisierung) einzelner Objekte an irgendwelche Variablen erfolgt während dem Durchlauf der Konstruktoren.

Methoden gehören in den Bereich "Aufbau".
Die this-Referenz in den Bereich "Zuweisung".
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Oben