# Vererbung in Java



## ak0004 (24. Jan 2010)

Morgen zusammen.

Vorweg, JA es handelt sich hierbei um Hausaufgaben, aber ich verzweifele hier einfach an dieser SCHE... Aufgabe.???:L

-------------------------------------------
Aufgabenstellung PDF DOWNLOAD
-------------------------------------------
Mein bisheriges Werk DOWNLOAD
-------------------------------------------

Mein Hauptproblem ist, wenn ich das mit der Vererbung richtig verstanden habe, was meine Super und was meine Sub-Klassen sind. Und das ich irgendwie ein Klasse als Sub und als Super Klasse habe.

So zur kurzen beschreibung meines bisherigen Werkes. Es soll die GesamtImpedanz(Gesamt Wiederstand) einer elektrischen Schaltung errechnet werden, mithilfe komplexer Zahlen.
Angelegt hab ich bis jetzt 5 Klassen.
Complex.java
Impedanz.java
Asynchronmotor.java
NYYLeitung.java
Simulation.java

Laut Aufgabenstellung soll ich die Klasse Impedanz.java aus der Klasse Complex.java ableiten.
Und die Asynchronmotor.java und die NYYLeitung.java aus der Klassse Impedanz.java.

Das heisst das Impedanz gleichzeitig Sub und Super sein müsste.Richtig?

Laut Aufgabenstellung, wird der ein Objekt vom Typ Asynchronmotor wie folgt erzeugt:

[Java]M1 = new Asynchronmotor("M1",400,20e3,0.9,0.9)// Bezeichnung,Volt,kW,CosPhi,Wirkungsgrand[/Java]
Soweit ist das klar, das klappt auch. Wenn ich jetzt aber die Klasse Asynchronmotor.java mit extends Impedanz erweitere welche auf Complex verweisst ... will Eclipse, das ich in dem Aufruf von M1 noch 2 weitere Argumente hinzufüge, nämlich der relle und der imaginäre Teil welcher in Complex verwendet wird.

Diese hab ich aber noch nich, weil die das Programm ja erst berechnen soll....???:L ICH RAFFS EINFACH NICHT


----------



## Wortraum (24. Jan 2010)

Es ist wohl sinnvoller, die Zeilen mitsamt dem auftretenden Fehler hier zu veröffentlichen.

Ob es der Fehler ist, den Du meinst, weiß ich nicht, aber mir ist aufgefallen, daß im Kontruktor von _Asynchronmotor_ ein Aufruf des Konstruktors der Oberklasse (= Superklasse) fehlt. Übrigens sollte genau das auch Eclipse melden.

Zum Verständnis: Wird ein Objekt erzeugt, werden der Konstruktor und nacheinander die Konstruktoren seiner Oberklassen aufgerufen. Das ist notwendig, da ja auch geerbte Variablen initialisiert werden müssen.

Normalerweise gibt es in jeder Klasse einen Standardkonstruktor, der keinerlei Parameter hat. Schreibt man jedoch selbst einen Konstruktor, so wie Du in Impendanz und Asynchronmotor, hat die Klasse auch keinen Standardkonstruktor mehr.

Bei Dir hat Asynchronmotor zwar nun einen selbstgeschriebenen Konstruktor, aber welcher Konstruktor der Klasse Impedanz aufgerufen werden soll, hast Du darin nicht angegeben. Den Standardkonstruktor kann Java nicht finden, da es ihn in Impedanz nicht gibt. Hier fehlt also ein Aufruf von _super(a, b)_, so wie es auch im Konstruktor von Impedanz geschieht.

In die Aufgabe werde ich mich aber nicht vertiefen, um zu schauen, wie es sein sollte. Aus dem Kontext scheint es so, daß jeder Asynchronmotor als Impedanz aufgefaßt werden kann, die man angeben muß, woraus am Ende eine Gesamtimpedanz berechnet werden soll. (Die Verbung bedeutete ja: jeder Asynchronmotor ist auch eine Impedanz.)

> Das heisst das Impedanz gleichzeitig Sub und Super sein müsste.Richtig?

Ja.


----------



## SlaterB (24. Jan 2010)

> dem Aufruf von M1
dem Konstruktor oder irgendeinem späteren Methodenaufruf, von welchem Typ ist die Variable M1

bitte genaue Fehlermeldung, z.B. Screenshot von Eclipse mit der unterstrichenden Stelle 

------


was auf jeden Fall nötig ist, ist ein Aufruf des Konstruktors der Super-Klasse Impedanz
da gibt es nur 

```
public Impedanz(double a, double b) 
	{
		super(a,b);
	}
```
zur Auswahl, welcher es dir vormacht, korrekt einen Konstruktor der eigenen Super-Klasse aufruft


für Asynchronmotor gilt das genauso, die wenigen grundlegenden Dinge zur Vererbung vergessen?
korrekter Aufruf eines Super-Konstruktors doch quasi das einzig komplizierte was man auf jeden Fall machen muss

```
public Asynchronmotor( String a, double b, double c, double d, double e)
	{
   // hier als allererstes super(0,0); oder sonst irgendwelche Werte
		this.Bezeichnung=a;
		this.Volt=b;
		this.Pab=c;
		this.CosPhi=d;
		this.Wirkungsgrad=e; 
[..]
```
erst Werte berechnen und dann nach oben weiterleiten funktioniert leider nur schlecht, da der super-Aufruf der erste sein muss

mit "will Eclipse, das ich in dem Aufruf von M1 noch 2 weitere Argumente hinzufüge" hat das aber nur entfernt zu tun,
wenn du so komisch Fehler beschreibst, dann lieber nur die Fehlermeldungen posten


----------



## ak0004 (1. Feb 2010)

Sooo erstmal DANKE für die Hinweise und SORRY das ich erst jetzt antworte.

Hab den Tip mit dem super(0,0) übernommen und es läuft.

Momentan hänge ich ich an folgendem Prolem.


```
package simulationsprogramm;

public class Simulation 
{

	public static void main(String[] args) 
	{
		Asynchronmotor M1, M2;
		NYYLeitung L1, L2;
		Impedanz Zges;
		Complex U0, Iges, IL2, DeltaU;
		
		
		M1 = new Asynchronmotor("M1" , 400 , 20e3 , 0.9 , 0.9);
		M2 = new Asynchronmotor("M2" , 400 , 15e3 , 0.9 , 0.9);
		L1 = new NYYLeitung("L1", 10.0, 50);
		L2 = new NYYLeitung("L2", 4.0, 25);
		
		
		System.out.println(L1);
		System.out.println(M1);
		System.out.println(L2);
		System.out.println(M2);
		
		Zges =M2.reihe(M1); //HIER IST DER FEHLER
                // Fehler lautet: Type Mismatch: Cannot convert from Complex to Impedanz
	}

}
```

Hier die aktuelle Klasse Impedanz

```
package simulationsprogramm;

public class Impedanz extends Complex
{	
	public Impedanz(double a, double b) 
	{
		super(a,b);
	}
	public Complex reihe(Complex uebergabe)
	{
		return add(uebergabe);
	}
	
	public Complex par(Complex uebergabe)
	{
		return  mul(uebergabe).div(add(uebergabe));
	}
}
```


Hier die aktuelle Klasse Complex

```
package simulationsprogramm;

public class Complex {
	
	protected double re ,im ;
	
	public Complex( double a, double b)
	{
		re = a;im = b;
	}
	
	public Complex add(Complex uebergabe)
	{
		return new Complex(re+uebergabe.re , im +uebergabe.im);
	}
	
	public Complex sub(Complex uebergabe)
	{
		return new Complex(re-uebergabe.re , im -uebergabe.im);
	}
	
	public Complex mul(Complex uebergabe)
	{
		return new Complex((re*uebergabe.re)-(im*uebergabe.im) , (re*uebergabe.im)+(im*uebergabe.re));
	}
	
	public Complex div(Complex uebergabe)
	{
		return new Complex(((re*uebergabe.re)+(im*uebergabe.im)) / ((uebergabe.re*uebergabe.re)+(uebergabe.im*uebergabe.im))
						 ,((im*uebergabe.re)-(re*uebergabe.im))  / ((uebergabe.re*uebergabe.re)+(uebergabe.im*uebergabe.im)));
	}

	public String toString()
	{
		return new String("("+re+",j"+im+")");
	}
}
```

Warum meckert Eclipse jetzt? Und warum willes convertieren... Impedanz ist doch mit extends Complex ausgestattet? Oder hab ich da mal wieder was falsch verstanden?

Könnte es eventuell an meinem Rückgabewert liegen? Complex gibt einen String zurück, Impedanz tut dies nicht!?!?


----------



## SlaterB (1. Feb 2010)

der Rückgabetyp ist Complex, es kann ein beliebiges Complex-Objekt nicht, nicht unbeding Impedanz, welches von Complex erbt

falls der abgebildete Code aus Impedanz drankommt: dort ruft reihe() doch add() auf, und darin steht 'return new Complex',
es wird also garantiert kein Impedanz zurückgegeben,


----------



## ak0004 (1. Feb 2010)

Okay....klingt irgendwie logisch. soll heissen mein Problem liegt in der Klasse Complex

in diesem Fall in der Funktion


```
public Complex add(Complex uebergabe)
	{
		return new Complex(re+uebergabe.re , im +uebergabe.im);
	}
```

wenn ich diese jetzt mit dem Rückgabewert Impedanz belege funtz das aber nich.....


```
public Complex add(Complex uebergabe)
	{
		return new Impedanz(re+uebergabe.re , im +uebergabe.im);
	}
```


----------



## SlaterB (1. Feb 2010)

nach wie vor ist der Rückgabewert Complex, welcher nicht zu Impedanz passt

stell dir eine Variable Object vor:

```
Object o = null;
[unbekannter Code]
Impendanz z = o;
```
das kann doch nicht funktionieren, in o kann ein String, ein Array oder irgendwas komischen drinstecken,
wieso sollte der Compiler so einen Befehl hinnehmen? selbst wenn man so nett ist, in o ein Impendanz-Objekt zu stecken,
wie deine Änderung es macht, bleibt das ursprüngliche Problem dasselbe,

und Complex zu Impendanz ist nicht viel anders als Object zum Impendanz, falls du darauf pochst,
jede Superklasse kann beliebige andere Klassen sein, es muss nicht passen,
es KANN aber, dafür gibt es Casten


----------



## ak0004 (1. Feb 2010)

SlaterB hat gesagt.:


> nach wie vor ist der Rückgabewert Complex, welcher nicht zu Impedanz passt



check ich nicht...Der Rückgabewert ist Impedanz!!!! return new Impedanz:L

und was ist Casten...ich bin mal Google befragen was Casten ist:bahnhof:


:rtfmkay...casten ist gefunden in google, aber das würde ich wenns geht nicht machen

das muss man doch auch ohne casten lösen können!


----------



## SlaterB (1. Feb 2010)

der Rückgabetyp ist in der Methodensignatur beschrieben, was in der Methode passiert ist ganz egal,
das ist eine der Grundlagen der Objektorientierung, da kann ich kaum mehr was sagen


```
public Object get() {
  if (werfeMuenze()) {
    return "test";
  } else {
    return new int[5];
  }
}

String st = get(); // soll das auch akzeptiert werden?
```


----------



## ak0004 (1. Feb 2010)

Ich glaube jetzt ist der Groschen gefallen.

Mein Codeblock muss also wie folgt aussehen

[Java]
	public Impedanz reihe(Complex uebergabe)
	{
		return new Impedanz(re+uebergabe.re , im +uebergabe.im);
	}
[/code]

Oder?


----------



## SlaterB (2. Feb 2010)

es ginge auch wenn du die Klasse Complex ganz löschst und nur Impedanz programmierst..,
also ja, diese Änderung würde helfen, aber die ganze Vererbung ad absurdum führen

dann doch lieber Casten


----------



## ak0004 (2. Feb 2010)

SlaterB hat gesagt.:


> es ginge auch wenn du die Klasse Complex ganz löschst und nur Impedanz programmierst..,



stimmt wohl, weil ich damit ja nicht mehr .add() aufrufe.

Naja da Complex aber gefordert wird, werd ich wohl ums casten nicht drum herum kommen.

Hmm nagut. Vielen Dank für eure/Deine Hilfe

Gruß AK0004


----------

