Skip to main content

So funktioniert in Java die Vererbung für Klassen und Objekte


java programmierung vererbung klassen objekte

Im letzten Beitrag habe ich dir das Java Vererbung Konzept an einem Beispiel vorgestellt.
In dem Beispiel-Rollenspiel gab es Klassen zu Helden und Superhelden.

Ich habe dir die Vererbungshierarchien theoretisch erläutert.
Jetzt geht es ans Praktische.

In diesen Beitrag lernst du:

  • Wie du bestehende Java Klassen erweiterst
  • Wie du Objekte aus den erweiterten Klassen erstellen kannst.
  • Welche Auswirkung diese Vererbung auf die einzelnen Objekte der Klassen hat.


Doch bevor wir mit dem Rollenspiel weiter machen…..
Lass mich zwei Fragen klären:

  • „Was ist ein Rollenspiel?“
  • „Und warum ist ein Rollenspiel ein wunderbares Beispiel zur Java Vererbung?“

Die Helden in einem Rollenspiel haben gewisse Eigenschaften, wie Schlagkraft, Schnelligkeit usw.
Die Werte, welche sie für diese Eigenschaften zugewiesen bekommen sind abhängig vom Beruf und Geschlecht.

Die Protagonisten in so einem Rollenspiel könnten vom Beruf her:

  • Piraten
  • Bogenschützen
  • Berserker
  • Magier
  • Oder vielleicht Ritter sein.

Und jeder Beruf bringt seine Besonderheiten mit.

  • Ein Pirat hat mehr Schlagkraft als eine Piratin.
  • Der Bogenschütze ist schneller als ein Pirat.
  • Und ein Berserker wäre stärker als ein Bogenschütze oder Pirat.

Die Auswahl des Berufes und des Geschlechtes spielen somit eine entscheidende Rolle bei den Startwerten für das Spiel.

Aber es geht noch weiter.
Immer wenn die Helden andere Gegner besiegen, sammeln sie Erfahrungspunkte.
Ab einer bestimmten Anzahl an Erfahrungspunkten steigen die Helden in ihrem Erfahrungslevel auf.

Das bedeutet dann, dass sich die Eigenschaften ändern.
Die Helden im Spiel werden durch den Aufstieg schneller, stärker usw.

Also dann – Los gehts.

Java Klassen sind Schablonen für Java Objekte.

Wir bleiben beim Rollenspiel.

Wir haben die Klasse Helden und deren Instanzvariablen.
Und wir haben die Klasse „ProgrammStart“ mit der main-Methode.


Wie du siehst, habe ich ein neues Java-Projekt „JavaRollenSpiel“ angelegt.
Und dieses beinhaltet beide Klassen.

Schauen wir uns den Code in der Klasse Held einmal an.


Keine Angst – der Java Code dazu kommt gleich…

Du siehst hier einen ganzen Haufen Attribute für die Helden.
Außerdem bietet die Klasse zwei Methode an:

  • die gibInfos()-Methode gibt alle Informationen zum Helden auf der Konsole aus.
  • die kaempfen()-Methode erhöht die Anzahl der Erfahrungspunkte, in Abhängigkeit der Gegnerzahl.
    Pro Gegner bekommt der Held 10 Punkte auf seine bisherigen Punkte drauf.

Und hier der Code zum Mitschreiben:


public class Held {
	String geschlecht;// männlich oder weiblich
	String vorName;// Name des Helden
	int groesse;// Größe in Zentimetern
	int aktErfahrungspunkte;//Wird nach jedem Kampf erhöht
	int aktLevel;// aktuelles Erfahrungslevel des Helden - Level ist abhängig von Erfahrungspunkten
	int schlagKraft;//die Schlagkraft des Helden ist abhängig vom Beruf und Geschlecht - steigert sich nach Levelaufstieg
	int ausdauer;// die Ausdauer des Helden ist abhängig vom Geschlecht und Beruf - steigert beim Aufleveln
	int schnelligkeit;// Schnelligkeit des Helden ist abhängig vom Beruf und Geschlecht - steigert sich nach Levelaufstieg
	int ruestungsLevel;// aktuelle Rüstungslevel ist abhängig vom Beruf und Geschlecht - steigert sich nach Levelaufstieg
	String beruf;// Pirat oder Berserker, Bogenschütze oder Superheld

	void gibInfos() {
		System.out.println("Geschlecht: " + geschlecht);
		System.out.println("Name: " + vorName);
		System.out.println("Beruf: " + beruf);
		System.out.println("Größe: " + groesse);
		System.out.println("Aktuelles Level: " + aktLevel);
		System.out.println("Schlagkraft: " + schlagKraft);
		System.out.println("Ausdauer: " + ausdauer);
		System.out.println("Schnelligkeit: " + schnelligkeit);
		System.out.println("Aktuelles Rüstungslevel: " + ruestungsLevel);
		System.out.println("Gesammelte Erfahrung: "+ aktErfahrungspunkte);
		System.out.println();// Leere Zwischenzeile
	}
	
	//Nach jedem Kampf bekommt der Held Erfahrungspunkte
	void  kaempfen(int anzahlGegner){
		aktErfahrungspunkte=aktErfahrungspunkte+10*anzahlGegner;//pro besiegten Gegner 10 Erfahrungspunkte
		System.out.println(vorName+" kämpft gegen "+anzahlGegner+" Gegner");
	}
}

Lege danach zwei Objekte in der Programmstart-Klasse an.
Weise diesen Objekten unterschiedliche Werte für die Attribute zu.

Java-Vererbung-Objekte

Und rufe die Info-Methoden am Objekt auf.

public class ProgrammStart {

	public static void main(String[] args) {
		Held jack = new Held();//neues Held-Objekt
		Held jaqueline = new Held();//neues Objekt aus der Klasse Held

		//Eigenschaften von Jack
		jack.vorName="Jack";
		jack.groesse=180;
		jack.ausdauer=15;
		jack.schlagKraft=22;
		jack.schnelligkeit=10;
		jack.ruestungsLevel=15;
		jack.beruf="Pirat";
		jack.geschlecht="männlich";
		jack.aktErfahrungspunkte=0;
		jack.aktLevel=1;
	
		//Eigenschaften von Jaqueline
		jaqueline.vorName="Jaqueline";
		jaqueline.groesse=166;
		jaqueline.ausdauer=35;
		jaqueline.schlagKraft=12;
		jaqueline.schnelligkeit=60;
		jaqueline.ruestungsLevel=5;
		jaqueline.beruf="Piratin";
		jaqueline.geschlecht="weiblich";
		jaqueline.aktErfahrungspunkte=0;
		jaqueline.aktLevel=1;
		
		//Aufruf der Info-Methoden
		jack.gibInfos();
		jaqueline.gibInfos();
		
	}
}

Du erhältst unterschiedliche Werte je nach Objekt.

Lass Jack und Jaqueline ruhig ein paar Kämpfe machen.
Und rufe dann noch einmal die Info-Methode auf.

public class ProgrammStart {

	public static void main(String[] args) {
		Held jack = new Held();
		Held jaqueline = new Held();

		//Eigenschaften von Jack
		jack.vorName="Jack";
		jack.groesse=180;
		jack.ausdauer=15;
		jack.schlagKraft=22;
		jack.schnelligkeit=10;
		jack.ruestungsLevel=15;
		jack.beruf="Pirat";
		jack.geschlecht="männlich";
		jack.aktErfahrungspunkte=0;
		jack.aktLevel=1;
	
		//Eigenschaften von Jaqueline
		jaqueline.vorName="Jaqueline";
		jaqueline.groesse=166;
		jaqueline.ausdauer=35;
		jaqueline.schlagKraft=12;
		jaqueline.schnelligkeit=60;
		jaqueline.ruestungsLevel=5;
		jaqueline.beruf="Piratin";
		jaqueline.geschlecht="weiblich";
		jaqueline.aktErfahrungspunkte=0;
		jaqueline.aktLevel=1;
		
		//Aufruf der Info-Methoden
		jack.gibInfos();
		jaqueline.gibInfos();
		
		//Jack kämpft gegen 5 und 2 Gegner
		jack.kaempfen(5);//jack kämpft gegen 5 -Zuwachs 50 Erfahrungspunkte
		jack.kaempfen(2);//Zuwachs um weitere 20 Erfahrungspunkte
		
		//Neue Erfahrungswerte nach dem Kampf
		jack.gibInfos();//Jack hat jetzt 70 Erfahrungspunkte
		jaqueline.gibInfos();//Jaqueline bleibt bei 0 Erfahrungspunkten
	}
}

Probiere es aus und klicke auf Run.

Du siehst, dass die Kämpfen-Methode Einfluss auf die Objekte hat.
Und zwar einen unterschiedlichen (separaten) Einfluss.

Du bist also in der Lage zwei Objekte zu erschaffen.
Und beide Objekte haben die gleichen Eigenschaften mit unterschiedlichen Werten.
Durch Methoden kannst du einen separaten Einfluss auf die Eigenschaftswerte eines jeden Objektes nehmen.

Du kannst sagen, dass sich die Objekte unterschiedlich entwickeln lassen.

Und genauso muss doch ein Rollenspiel sein, oder?

Die Klassen bestimmen somit, welche Eigenschaften (Beruf, Name) deine Objekte später haben dürfen und welche nicht.
Somit fungieren die Klassen als eine Art Schablone oder Muster für deine Objekte.
Oder man kann sagen, die Objekte erben die Attribute aus ihrer Klasse.

Aber das reicht nicht.
Denn schau dir doch einmal ganz genau die einzelnen Attribute an.

Mal ganz ehrlich –
Wenn so ein Held auf die Rollenspiel-Welt kommt, hat dieser doch immer Level 1 und immer 0 Erfahrungspunkte.

Es ist doch besser dies zu standardisieren, anstatt dies bei jedem neuen Helden mit immer gleichbleibenden Wert zuzuweisen, oder?

Also kommen wir zur zweiten Schablone.

Eine zweite speziellere Schablone schaffst du mit dem Konstruktor.

Die Klasse war schon eine gute Schablone.
Wir machen diese Schablone jetzt etwas spezifischer- fassen diese somit enger.

Denn neue Helden kommen mit einem Level von 1 und mit 0 Erfahrungspunkten auf die Welt.
Das ist eine feste Regel in unserem Rollenspiel und muss nicht extra zugewiesen werden.

Zurück in die Heldenklasse…..
Und dort legst du einen Konstruktor an.
Und im Rumpf des Konstruktors kannst du diese Standardwerte direkt zuweisen.

public class Held {
	String geschlecht;
	String vorName;
	int groesse;
	int aktErfahrungspunkte;
	int aktLevel;
	int schlagKraft;
	int ausdauer;
	int schnelligkeit;
	int ruestungsLevel;
	String beruf;
	
	//parameterloser Konstruktor weist Werte zu
	Held (){
		this.aktErfahrungspunkte=0;//Standardpunkte für neue Helden
		this.aktLevel=1;//Standarlevel für neue Helden
	}
	
	void gibInfos() {
		System.out.println("Geschlecht: " + geschlecht);
		System.out.println("Name: " + vorName);
		System.out.println("Beruf: " + beruf);
		System.out.println("Größe: " + groesse);
		System.out.println("Aktuelles Level: " + aktLevel);
		System.out.println("Schlagkraft: " + schlagKraft);
		System.out.println("Ausdauer: " + ausdauer);
		System.out.println("Schnelligkeit: " + schnelligkeit);
		System.out.println("Aktuelles Rüstungslevel: " + ruestungsLevel);
		System.out.println("Gesammelte Erfahrung: "+aktErfahrungspunkte);
		System.out.println();// Leere Zwischenzeile
	}
	
	//Nach jedem Kampf bekommt der Held Erfahrungspunkte
	void  kaempfen(int anzahlGegner){
		aktErfahrungspunkte=aktErfahrungspunkte+10*anzahlGegner;//pro besiegten Gegner 10 Erfahrungspunkte
		System.out.println(vorName+" kämpft gegen "+anzahlGegner+" Gegner");
	}
}

In der Programmstartklasse kannst du diese Zuweisungen jetzt löschen oder so wie ich – einfach auskommentieren.

public class ProgrammStart {

	public static void main(String[] args) {
		Held jack = new Held();
		Held jaqueline = new Held();

		//Eigenschaften von Jack
		jack.vorName="Jack";
		jack.groesse=180;
		jack.ausdauer=15;
		jack.schlagKraft=22;
		jack.schnelligkeit=10;
		jack.ruestungsLevel=15;
		jack.beruf="Pirat";
		jack.geschlecht="männlich";
		//jack.aktErfahrungspunkte=0;
		//jack.aktLevel=1;
	
		//Eigenschaften von Jaqueline
		jaqueline.vorName="Jaqueline";
		jaqueline.groesse=166;
		jaqueline.ausdauer=35;
		jaqueline.schlagKraft=12;
		jaqueline.schnelligkeit=60;
		jaqueline.ruestungsLevel=5;
		jaqueline.beruf="Piratin";
		jaqueline.geschlecht="weiblich";
		//jaqueline.aktErfahrungspunkte=0;
		//jaqueline.aktLevel=1;
		
		//Aufruf der Info-Methoden
		jack.gibInfos();
		jaqueline.gibInfos();
		
		//Jack kämpft gegen 5 und 2 Gegner
		jack.kaempfen(5);//jack kämpft gegen 5 -Zuwachs 50 Erfahrungspunkte
		jack.kaempfen(2);//Zuwachs um weitere 20 Erfahrungspunkte
		
		//Neue Erfahrungswerte nach dem Kampf
		jack.gibInfos();//Jack hat jetzt 70 Erfahrungspunkte
		jaqueline.gibInfos();//Jaqueline bleibt bei 0 Erfahrungspunkten
	}
}

Klicke auf Run.
Und alle Infos zum Objekt werden dir ausgegeben.
Beide Objekte haben durch den Konstruktor Standard-Startwerte für die Erfahrungspunkte und das Erfahrungslevel bekommen.

Okay, okay.
Aber eigentlich ist es doch so, dass die Eigenschaften Stärke, Schnelligkeit und Ausdauer irgendwie mit dem Beruf und mit dem Geschlecht zusammenhängen.

Ein männlicher Pirat startet mit anderen Werten, als ein weiblicher.
Eine Bogenschützin hat wiederum andere Startwerte, als ein Berserker.

Meine Frage an Dich:
Kann ich nicht einfach in die Klasse Held einen besseren Konstruktoren anbieten?

Zum Beispiel:
Der Konstruktor erwartet das Geschlecht, den Namen und den Beruf.
Und im Rumpf des Konstruktor werden die Startwerte verteilt.

Bei einem männlichen Piraten:

  • schlagKraft=22;
  • ausdauer=15;
  • schnelligkeit=10;

Wenn es sich um einen weiblichen Piraten handelt, lauten die Startwerte:

  • schlagKraft=12;
  • ausdauer=35;
  • schnelligkeit=60;

Bei einem männlichen Bogenschützen, wären die Startwerte:

  • schlagKraft=12;
  • ausdauer=12;
  • schnelligkeit=80;

Und dieses Prinzip kann ich dann für alle Beruf-Geschlechtskombination anbieten?
Klar geht das – mit einer Menge if und else Blöcken im Konstruktor.

Und immer wenn du das Rollenspiel, um Berufe wie Magier, Ritter oder Hexenmeister, erweiterst – legst du neue if-else Konstrukte an.

Halt!!!
Das ist doch viel zu kompliziert und auch viel zu unflexibel, oder?
Jede Spezialisierung führt dann unweigerlich zu einer höheren Komplexität.

Das Zauberwort heißt Vererbung.

Die beste Schablone für speziellere Klassen findest du bei der Java Vererbung.

Wenn Bogenschützen, Magier und Ritter alles Helden sind – dann ist der Pirat und auch die Piratin ein Spezialfall unter den Helden.
Und natürlich ist dann auch jeder Magier, Ritter usw. ein Spezialfall.

Denn diese Helden sind allesamt speziell, weil sie sich aufgrund ihrer Werte (Kraft, Ausdauer) deutlich von anderen Spezialfällen unterscheiden.

Also was machen wir?
Wir legen jetzt Spezialklassen an.

Für den Anfang lege bitte:

  • eine Klasse namens Pirat,
  • und eine Klasse Piratin an

Alle beiden Klassen erweitern die Klasse „Held“.

Und das bedeutet:
Sie erhalten automatisch alle Instanzvariablen der Heldenklasse.
Sind aber in der Lage jeder einen unterschiedlichen Standardwert zuzuweisen.

Ich führe dies einmal beim Pirat und bei der Piratin vor:
Die Klasse Pirat extends bzw. erweitert die Klasse Held:


public class Pirat extends Held {

}

Die Klasse Piratin erweitert die Klasse Held ebenfalls.


public class Piratin extends Held {

}

In beiden Klassen kannst du jetzt einen Konstruktor anbieten, welcher Argumente für den Namen und die Größe erwartet.
Denn das sollen dann die einzigen-Nicht-Standardwerte sein.

public class Pirat extends Held {

	Pirat (String vorName, int groesse){
		this.vorName=vorName;
		this.groesse=groesse;
		this.ausdauer=15;
		this.schlagKraft=22;
		this.schnelligkeit=10;
		this.ruestungsLevel=15;
		this.beruf="Pirat";
		this.geschlecht="männlich";
	}
}

Und die Klasse Piratin mit anderen Startwerten:

public class Piratin extends Held{

	Piratin (String vorName, int groesse){
		this.vorName=vorName;
		this.groesse=groesse;
		this.ausdauer=35;
		this.schlagKraft=12;
		this.schnelligkeit=60;
		this.ruestungsLevel=5;
		this.beruf="Piratin";
		this.geschlecht="weiblich";
	}
}

Zurück in der Klasse Programmstart, kannst du Objekte der Klasse Pirat und Piratin anlegen.
Diese beiden Objekte besitzen dann alle Eigenschaften der Klasse Held mit standardisierten Piraten-Werten.

public class ProgrammStart {

	public static void main(String[] args) {
		Pirat jack = new Pirat("Jack",180);//Piratobjekt welches vom Held-Objekt erbt
		Piratin jaqueline = new Piratin("Jaqueline",166);//Piratinobjekt, welches vom Held Objekt erbt
		
		//Aufruf der Info-Methoden
		jack.gibInfos();
		jaqueline.gibInfos();
		
		//Jack kämpft gegen 5 und 2 Gegner
		jack.kaempfen(5);//jack kämpft gegen 5 -Zuwachs 50 Erfahrungspunkte
		jack.kaempfen(2);//Zuwachs 20 Erfahrungspunkte
		
		//Neue Erfahrungswerte nach dem Kampf
		jack.gibInfos();
		jaqueline.gibInfos();
	}
}

Probiere es aus.
Lege noch zwei Piraten oder Piratinnen an.

Jeder neue Pirat oder Piratin startet dann mit standardisierten Piratenwerten ins Spiel.
Das Erfahrungslevel und die Startpunkzahl bekommen alle Objekte weiterhin vom Konstruktor der Heldklasse.
Den Rest liefert die jeweilige Unterklasse.

Cool oder?
Du siehst, mit der ganzen Java Vererbung bekommst du richtig geile Möglichkeiten spezielle Unterklassen zu bilden.

Na wie wärs…
Implementiere doch noch den Bogenschützen, den Berserker oder andere Spezialklassen in das Projekt.

Zusammenfassung:

  • Alle Java Klassen bieten schon eine sehr schöne Schablone oder Bauplan für spätere Objekte.
  • Durch den Einsatz von Konstruktoren kannst du das Zusammenbauen der Objekte noch weiter spezialisieren und individualisieren.
  • Die speziellste Schablone bietet dir allerdings Java durch Vererbung an.
  • Du kannst Unterklassen anlegen, welche alle Instanzvariablen der Oberklasse erben.
  • Diese Instanzvariablen kannst du dann für jede Unterklasse mit unterschiedlichen Startwerten ausstatten.

Über den Autor

wissen
Folge Sciodoo und bleibe stets auf dem Laufenden. Schließ dich uns an und abonniere unseren Instagram-Kanal ein. Wir stellen täglich neue Artikel für dich rein.
Weiter zum Kanal>>>
     

Ähnliche Beiträge