Vererbung Aufwärtsvererbung

Katzenstreu

Mitglied
Hallo liebe Programmierer!

überall lese ich von der Möglichkeit zu Vererben (Stichwörter:
"extends" und "super()"). Dies klappt in gewohnte Richtung korrekt.
Ich zitire zur Fragestellugn dieses Beispiel(bild). Dort geht es um
die Superklasse "Stift" und zwei Subklassen, "Druckbleistift" und
"Kugelschreiber".

Ich habe in meinem Fall toString()-Methoden für die Super- und
Subklassen programmiert.

Frage:
Wie kann ich eine Unterklasse (teilweise) im Format der Super-
klasse ausgeben? Also nur die Eigenshaften/Variablen ausgeben,
die auch die Hauptklasse besitzt?

Vielen Dank!
Tim

P.S.: In meinem eigentlichen Problem geht es um die Superklasse
"Kontakt" und deren zwei Unterklassen "Lieferant" und "Kunde". :)

Nebenfrage:
Kann man alle (meine) Klassen in Eclipse grafisch darstellen?
 
Zuletzt bearbeitet:

Helgon

Bekanntes Mitglied
Wenn die variablen/Methoden der Super-Klasse public sind, kannste einfach drauf zugreifen, ansonsten getter/setter Methoden dafür in der Hauptklasse schreiben
 

Schandro

Top Contributor
Du überschreibst toString, rufst mit super das toString der Vaterklasse auf, modifizierst das Ergebnis und returnst es.
 

Katzenstreu

Mitglied
Noch kann ich euch nicht ganz folgen. Erstmal die drei Quälcodes:

Klasse Kontakt:
Java:
package Aufgabe3;

public class Kontakt {
	String name;
	String stadt;
	String straße;
	String hausnummer;
	int plz;
	
	public Kontakt(String n, String sta, String str, String h, int p){
		name = n;
		stadt = sta;
		straße = str;
		hausnummer = h;
		plz = p;
	}
	
	public String toString(){
		return name+", "+straße+" "+hausnummer+", "+plz+" "+stadt;
	}

}
Klasse Lieferant:
Java:
package Aufgabe3;

public class Lieferant extends Kontakt{
	String lieferweise;
		
	public Lieferant(String n, String sta, String str, String h, int p, String l){
		super(n, sta, str, h, p);
		lieferweise = l;
	}
	
	public String toString(){
		return super.toString() +", lieferweise "+lieferweise;
	}

}
Klasse Kunde:
Java:
package Aufgabe3;

public class Kunde extends Kontakt{
	boolean mitMwSt;
	String s;
		
	public Kunde(String n, String sta, String str, String h, int p, boolean m){
		super(n, sta, str, h, p);
		mitMwSt = m;
	}
	
	public String toString(){
		s = ", ausgewiesen ohne Mehrwertsteuer";
		if (mitMwSt){
			s = ", ausgewiesen mit Mehrwertsteuer"
		;}
		return super.toString()+s;
	}

}

Kunden werden mit dem boolean-Parameter mitMwSt ausgestattet,
Lieferanten haben ihre lieferweise als String angegeben. Es sind also
nur kleine Veränderungen.
Jedoch wüsste ich gerne, wie ich mit System.out.println() einen Kun-
den als Kontakt ausgebe (d.h. ohne die Angabe des MwSt.-Parameters.
 

jgh

Top Contributor
mmmh, wenn ich ehrlich bin, hatte ich erwartet, dass ein Cast zum Kontakt ausreicht um die toString() der Vaterklasse (also des Kontaktes) aufzurufen..., aber dem ist nicht so!

Java:
	Kunde kunde = new Kunde("Hans", "Hamburg", "Elbstraße", "42", 20523,
				false);
System.out.println(kunde); // klar, die toString des Kunden
System.out.println(((Kontakt) kunde)); // ruft immer noch die toString() vom Kunden auf
Kontakt kontakt = (Kontakt)kunde;
System.out.println(kontakt); // ruft auch die toString() vom Kunden auf

irgendwas war da mal....aber was^^
 

bERt0r

Top Contributor
Wenn du ein Objekt hast, kannst du nicht einfach auf Funktionen irgendwelcher Superklassen des Objektes zugreifen, die überschrieben worden sind. Du kannst aber von innerhalb des Objekts mittels super.funktion() auf Methoden deiner Superklasse zugreifen.
Kleines Beispiel - der lange Exceptionblock kommt davon, weil ich mal schauen wollte ob mans mit Reflection hinbekommen könnte, Fehlanzeige:
Java:
import java.lang.reflect.InvocationTargetException;
public class VererbungTest 
{
	class Fahrzeug
	{
		int speed;
		Fahrzeug(int spd)
		{
			speed=spd;
		}
		public void fahr()
		{
			System.out.println("Fahrzeug fährt mit "+speed);
		}
	}
	
	class Auto extends Fahrzeug
	{
		String fahrer;

		Auto(int spd, String fhrer)
		{
			super(spd);
			fahrer=fhrer;
		}
		
		@Override
		public void fahr()
		{
			System.out.println("Auto von "+fahrer+" fährt mit "+speed);
		}
		
		public void superFahr()
		{
			super.fahr();
		}
	}
	
	public VererbungTest()
	{
		Auto a=new Auto(100,"Bertl");
		a.fahr();
		try {
			a.getClass().getSuperclass().getMethod("fahr").invoke(a);
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		a.superFahr();
	}
	
	public static void main(String args[])
	{
		new VererbungTest();
	}
}
 

Katzenstreu

Mitglied
Okay, es beruhigt mich zu hören, dass diese Fragestellung doch nicht so trivial ist.
Nun habe ich folgenden Codeschnipsel in die Unterklassen kopiert:
Java:
public String toSuperString(){
	return super.toString();
}
Nun funktioniert der Aufruf, etwas umständlich mit expliziter toSuperString()-Methode wie folgt:
Java:
System.out.println(testKunde);
System.out.println(testKunde.toString());
System.out.println(testKunde.toSuperString());

System.out.println(lieferantHeher);
System.out.println(lieferantHeher.toString());
System.out.println(lieferantHeher.toSuperString());
Die Ausgabe liefert wie gewünscht die verkürzte UND die ausführliche Version:
Code:
Peter Forkasz, Möscezk Maisizce 11, 4540997 Bangladésh, ausgewiesen mit Mehrwertsteuer
Peter Forkasz, Möscezk Maisizce 11, 4540997 Bangladésh, ausgewiesen mit Mehrwertsteuer
Peter Forkasz, Möscezk Maisizce 11, 4540997 Bangladésh
Heher, Oldenfelder Bogen 43b/c, 22147 Hamburg, lieferweise persönlich
Heher, Oldenfelder Bogen 43b/c, 22147 Hamburg, lieferweise persönlich
Heher, Oldenfelder Bogen 43b/c, 22147 Hamburg

Code zu kopieren sei böse, faselte der Prof. immer. Habt ihr eine Idee, wie ich den Codeschnipsel am Anfang dieses Posts auslagern kann?

Grüße
Tim ;)
 
Zuletzt bearbeitet:

Katzenstreu

Mitglied
Code kopieren ist nicht böse, aber Code kopieren ohne ihn zu kapieren schadet einem selber. ;)
Es geht nicht ums Abschreiben, sofern darum dass Copy&Paste für Unstimmigkeiten sorgen kann. Sodass Code an einem Ort geädert wird, an den anderen vergessen wird zu überarbeiten und so Probleme verursacht werden können. Auch dazu gibt es doch die Klassen/Objekte, die das Auslagern in dieser schönen Programmiersprache ermöglichen und Codedubletten verhindern können. Dachte ich. Ich muss wohl mal drüber schlafen - vielleicht fällt euch ja eine elegantere Methode ein.

Danke bis hier hin! :)
 
B

...ButAlive

Gast
Das was du vor hast wird so nicht gehen. Was du brauchst ist eine Klasse die den String erstellt. Also so was wie:

Java:
public class KontaktFormatter
{
	public static String formatKontakt(Kontakt kontakt){
		//return einen String der alle Felder des Kontaktes ausgibt;
	}
	
	public static String formatKunde(Kunde kunde){
		//return formatKontakt(kunde)+alle Kundenspezifischen Felder;
	}
	
	public static String formatLieferant(Lieferant lieferant){
		//return formatKontakt(lieferant)+alle Lieferantenspezifischen Felder;
	}
}

formatKontakt kann man mit einem Kunden oder mit einen Lieferanten aufrufen und bekommt nur den String für einen Kontakt zurück. Mit Vererbung kommt man da nicht weit. Aber für sowas ist toString eh nicht gedacht.
 

Schandro

Top Contributor
Es geht nicht ums Abschreiben, sofern darum dass Copy&Paste für Unstimmigkeiten sorgen kann. Sodass Code an einem Ort geädert wird, an den anderen vergessen wird zu überarbeiten und so Probleme verursacht werden können. Auch dazu gibt es doch die Klassen/Objekte, die das Auslagern in dieser schönen Programmiersprache ermöglichen und Codedubletten verhindern können. Dachte ich. Ich muss wohl mal drüber schlafen - vielleicht fällt euch ja eine elegantere Methode ein.
Klar sollte Code DRY sein, hat aber nicht so viel mit den Problemen zu tun die durch Copy&Paste entstehen können^^
 
I

IH

Gast
Also,
nur falls dich die Ursache für dein Problem interessiert (ich arbeite jetz mal mit Auto als Superklasse und Audi als Subklasse).
Ich denke es ist so, dass bei diesem Cast nicht tatsächlich eine Typumwandlung im Sinne von "der Audi ist jetz als Instanz von Auto gespeichert" sondern, dass nur von der VM eine neues Auto erzeugt wird, welches jedoch im Speicher tatsächlich noch immer auf den Audi zeigt.
Der Compiler behandelt das Objekt als wie ein Auto weil er ja auch ein Auto-Objekt an die Hand bekommt, aber im Speicher „merkt“ sich die VM durch das Referenzieren auf den gleichen Speicherbereich, dass es immer noch ein Audi ist.
Deswegen geht sowas auch nicht.
 
I

IH

Gast
Achja Stichwort "dynamic binding"....
hätte dein Programm sich so verhalten wie du es erwartet hättest, wäre das static binding gewesen. Das trifft in Java aber nur auf Attribute zu. Objektmethoden werden dynamisch gebunden in Java.
 

Oben