Java Vererbungsproblem

S-Force

Ensign
Registriert
Nov. 2007
Beiträge
238
Hallo,

ich habe eine Aufgabe und bin mir nicht sicher wie genau Java bei der Vererbung hier arbeitet. Ich hoffe mir kann jemand erklären warum der Java Compiler genau das macht was da rauskommt...

Code:
package Vererbung;

public class Main {

	public static void main(String[] args) {
		A a=new A();
		B b=new B();
		C c=new C();

		
		System.out.println(b.g()); //-> Ergebnis = 12 
		
		System.out.println(c.h()); //-> Ergebnis = 8
		
		System.out.println(c.i()); //-> Ergebnis = 8
	}
	

	public class A {

		private int a=1;
		private int b=2;
		protected int c=3;
		
		public int f(){
			return a;
		}
		
		public int g(){
			return f() +b;
		}
	}
	
	public class B extends A{

		protected int b=10;
		
		public int f(){
			return b;
		}
		
		public int h(){
			return h2() +c;
		}
		
		private int h2(){
			return 5;
		}
		
		public int i(){
			return super.f();
		}
	}
	
	public class C extends B {
		
		public int g(){
			return f() +b;
		}
		
		protected int h2(){
			return 6;
		}

	}



}

Warum kommt bei b.g() 12 und c.h() 8 als Ergebnis heraus?

Gruß
 
Hallo,

also b.g() ruft die Funktion der Klasse A auf. Diese addiert f()+b. Die Funktion f() gibt es sowohl in Klasse A als auch in B. Es wird die Funktion der Klasse B aufgerufen und nicht die der Klasse A. Also wird die Zahl 10 (definiert in Klasse B) mit b=2 addiert. Das ergibt 12.

Bei c.h() verhält sich das so:
Es wird die Funktion h() der Klasse B aufgerufen. Diese gibt h2 zurück, welches in Klasse B mit 5 definiert ist. Dabach wird c=3 aus Klasse A addiert. Ergebnis ist 8.

Möchtest du bestimmte Funktionen einer Klasse aufrufen musst du diese angeben. Außerdem kannst du nur Funktionen aufrufen welche in der Vererbungskette unterhalb der Klasse liegen die du verwendest. Du kannst also von b keine Funktion von c aufrufen, umgekehrt allerdings schon.

Ich hoffe das hilft.


mfg
cold
 
Ich wollte dir gerade die Lösung schreiben, da habe ich gelesen, dass es sich um eine Aufgabe handelt.

Daher nur ein paar Ratschläge. Um Vererbung richtig zu verstehen und Code besser lesen zu können, gibt es einen Modifizierer namens "override". Diesen benutzt man, wenn man will, dass eine Methode überschrieben wird. Dieser hilft hier ungemein. Zum Beispiel überschreibt Klasse B die Methode f() der Klasse A.
Code:
public override int f() { [...] }

Des Weiteren achte ganz genau auf die Zugriffsmodifikatoren public, protected und private! Besonders im Zusammenspiel von Klasse C und B.

P.S.: Das Ergebnis von c.i() sollte 1 sein und nicht 8.

EDIT:

coldplayed schrieb:
Außerdem kannst du nur Funktionen aufrufen welche in der Vererbungskette unterhalb der Klasse liegen die du verwendest. Du kannst also von b keine Funktion von c aufrufen, umgekehrt allerdings schon.

Denk darüber bitte noch einmal nach, du beschreibst genau dieses Verhalten in deinem ersten Absatz.

Es wird die Funktion der Klasse B aufgerufen und nicht die der Klasse A
obwohl du f() aus der Klasse A aufrufst.

Edit2:

Bei c.h() verhält sich das so:
Es wird die Funktion h() der Klasse B aufgerufen. Diese gibt h2 zurück, welches in Klasse B mit 5 definiert ist. Dabach wird c=3 aus Klasse A addiert. Ergebnis ist 8.

Du erklärst gar nicht, warum h2() nicht aus Klasse C aufgerufen wird. Ja, ich weiß die Lösung, aber der TE soll selber drauf kommen, warum dies eben nicht der Fall ist.
 
Zuletzt bearbeitet:
Danke für die Antworten.

Es ist eine Aufgabe aus einer Übungsklausur und ich bin sehr stark verwirrt.
1. c.i() ist 1 das war mein Fehler

Ok, also Zusammengefasst kann man sagen bei b.g()

-> Da b.g() nicht in B vorhanden ist muss auf A zugegriffen werden. f() kann dann aus B genutzt werden da es public ist. b wiederum in g() kann aber nicht aus B genutzt werden weil es protected ist.
 
So wie der Code da steht, hast du das aber nicht compiliert oder? Also eine Instanz einer inneren Klasse in der Main zu erstellen ohne static geht auf deine Wiese zumin. nicht.

Aber jetzt zum Thema.

Eigentlich ist es ziemlich offensichtlich warum die Ergebnisse heraus kommen.

Wenn du in der Main die einzelnen Instanzen wie b eintippst und dann Punkt => b. dann öffnen sich in einer IDE wie Eclipse alle Methoden die diese Instanz aufrufen kann.

Die Instanz b ruft die Methode g( Aus der Vaterklasse A) auf und diese Methode ruft, bevor sie die den return Wert gibt, auch eine Methode f auf. die Methode f ist aber nicht die Methode f aus der Klasse A sondern die aus B, weil du die Methode f in der Klasse B überschreibst.

Und den zweiten Aufruf erspare ich mir, weil das Prinzip das selbe ist.

Im letzten Aufruf kommt übrigens keine 8 sondern 1 raus. Denn mit dem Keyword super rufst du keine überschriebene Methode in dem Beispiel auf sondern die Methode f aus der Vaterklasse a auf.


Und beim nächsten mal bitte keine Buchstaben für Methoden oder für Instanzen, solcher Code ist echt anstrengend zu lesen.
 
Da b.g() nicht in B vorhanden ist muss auf A zugegriffen werden.
Richtig.
f() kann dann aus B genutzt werden da es public ist.
Nicht ganz. Es stimmt schon, aber nur weil es in A auch public ist (somit wird es überschrieben "override"). Als Stichwort: Es wird Polymorphie angewendet. Wäre es in A nicht public sondern private würde die Lösung anders sein. Probier es aus.
b wiederum in g() kann aber nicht aus B genutzt werden weil es protected ist.
Nein, es kann aus B nicht genutzt werden, weil Klasse A die Variablen der Klasse B nicht kennen kann.
 
So wie der Code da steht, hast du das aber nicht compiliert oder? Also eine Instanz einer inneren Klasse in der Main zu erstellen ohne static geht auf deine Wiese zumin. nicht.
Wie schon erwähnt ist das einfach nur eine Kopie aus einer Probeklausur und ich haben den Code natürlich nicht so in Java ausgeführt^^
Zusätzlich habe ich mich auch schon mehrmals über die Klassen/Variablen/Methoden Namen aufgeregt...

Nein, es kann aus B nicht genutzt werden, weil Klasse A die Variablen der Klasse B nicht kennen kann.

Ok dh. es wird die überschrieben Funktion f() aus B genutzt (weil sie in beiden public ist) aber die überschriebene Variable b nicht, da sie protected ist? ( ist für mich irgendwie nicht ganz logisch nachvollziehbar )
 
Methoden können überschrieben werden.
Variablen können nicht überschrieben werden. Sie können in Unterklassen (B bzw. C) nur verwendet werden, wenn sie public oder protected sind. Darum können die Unterklassen B und C nur auf die Variable c zugreifen, jedoch nicht auf a oder b.
 
Am besten tippst du den Code in eine IDE, und dann erkennst du ziemlich schnell nach dem Punktoperator was erlaubt ist und was nicht.
 
Zurück
Oben