# Problem mit ArrayList - Typen innerhalb der ArrayList



## I2oxxi (7. Dezember 2011)

Guten Abend 
Ich bin ein 20 jähriger Informatik Student der da ein kleines Problem bei einer Aufgabe hat ^^
Also ich fang mal direkt an zu beschreiben:
Ich soll eine eine Abstracte Klasse netz erstellen, mit bestimmten methoden, davon eine klasse resistor(wiederstand) ableiten, mit nem versteckten wiederstandswert und der methode ohm() (gibt wiederstandswert zurück).
Dazu kommen 2 Klassen, parallel und serial, die ein netz von wiederständen berechnen sollen.
Hier ist ein Netz dann eine ArrayList von Resistoren, die an den konstruktor von serial/parallel übergeben wird. 
Ich poste mal Codeausschnitte um mein Problem zu beschreiben:

Resistorklasse

```
package resistor;

public class resistor extends netz{
	
	private double wiederstand;
	private int anzahl;
	
	resistor(double wiederstand)
	{
		this.wiederstand = wiederstand;
		this.anzahl = 1;
	}
	
	public double ohm()
	{
		return this.wiederstand;
	}
	
	public int countresistors()
	{
		return this.anzahl;
	}

}
```

Serial Klasse (die parallel ist fast gleich, nur die berechnung des wiederstandes ist halt anders

```
package resistor;

import java.util.ArrayList;

public class serial {
	
	private resistor netz1;
	private resistor netz2;
	private int anzahl;
	private double wiederstand;
	private ArrayList<resistor> netze = new ArrayList<resistor>();
	
	public serial(ArrayList<resistor> netze)
	{
		for(int i=0; i<netze.size();i++)
		{
			this.netze.add(netze.get(i));
		}
	}
	
	public serial(resistor r1, resistor r2)
	{
		this.netz1=r1;
		this.netz2=r2;
	}
	
	public double ohm()
	{
		this.wiederstand = 0;

		if(this.netz1!=null&&this.netz2!=null)
		{
			this.wiederstand = this.netz1.ohm() + this.netz2.ohm();
			return this.wiederstand;
		}
		else
		{
			for(int i=0;i<netze.size();i++)
			{
				this.wiederstand+=this.netze.get(i).ohm();
			}
			return this.wiederstand;
		}
	
	}
	
	public int countresistors()
	{
		this.anzahl=0;
		
		if(this.netz1!=null&&this.netz2!=null)
		{
			this.anzahl=netz1.countresistors() + netz2.countresistors();
			return this.anzahl;
		}
		else
		{
			for(int i=0;i<netze.size();i++)
			{
				this.anzahl+=netze.get(i).countresistors();
			}
			return this.anzahl;
		}
	}

}
```

Modellierung der Schaltung (Anhang)

```
package resistor;

import java.util.ArrayList;

public class modellierung {

	
	
	public static void main(String[] args)
	{
	
		resistor r1=new resistor(100);
		resistor r2=new resistor(200);
		resistor r3=new resistor(300);
		resistor r4=new resistor(400);
		resistor r5=new resistor(500);
		resistor r6=new resistor(600);
		


		ArrayList<resistor> a1 = new ArrayList<resistor>();
		a1.add(r1);
		a1.add(r3);
		
		parallel p1 = new parallel(a1);
		System.out.println(p1.ohm());
		
		resistor h1 = new resistor(p1.ohm());
		
		ArrayList<resistor> a2 = new ArrayList<resistor>();
		a2.add(h1);
		a2.add(r2);
		
		serial s1 = new serial(a2);
		System.out.println(s1.ohm());
		
		resistor h2 = new resistor(s1.ohm());
		
		ArrayList<resistor> a3 = new ArrayList<resistor>();
		a3.add(r4);
		a3.add(r5);
		
		serial s2 = new serial(a3);
		System.out.println(s2.ohm());
		
		resistor h3 = new resistor(s2.ohm());
		
		ArrayList<resistor> a4 = new ArrayList<resistor>();
		a4.add(h2);
		a4.add(r6);
		a4.add(h3);
		
		parallel p2 = new parallel(a4);
		System.out.println(p2.ohm());
		System.out.println(p2.countresistors());
		
	
		
	}
}
```

Sind noch ein paar zwischensachen mit drin, weil man nach der Aufgabe am Anfang nur 2 eingehende Resistoren pro Serial/Parallel Netz haben sollte, und es dann auf mehrere erweitern sollte.


Wie man sieht muss ich bei der Modellierung mit HilfsObjekten arbeiten, was auch das problem darstellt. die methode countresistors() gibt 3 aus, da ich ja alles über hilfsobjekte laufen lassen musste.
Mein Problem liegt hier bei ArrayList<resistor>.
Gibt es eine möglichkeit, den typ offen zu lassen? so dass die liste  resistor/serial/parallel objekte gleichzeitig enthalten kann?
so könnte ich dann eine array list von:
r6
s1 = serial(r4,r5)
s3 = serial(r2,p1)       p1 = parallel(r1,r3)

machen und darüber ein parallel object erstellen, was auch dann die Resistoren richtig zählen würde.
ich hoffe ihr versteht wie ich es meine ^^


----------



## Bratkartoffel (7. Dezember 2011)

Hi und herzlich Willkommen hier bei tutorials.de,

mach dir ein Interface und lasse deine 3 Klassen dieses implementieren.
Dann kannst du das Interface als Typ für die ArrayList nehmen.

Übrigens: In Java schreibt man die Klassen normalerweise mit einem Großbuchstaben am Anfang 

Gruß
BK


----------



## I2oxxi (7. Dezember 2011)

okay, danke für den tipp, dann werd ich mal schauen wie genau das mit dem interface funktioniert, hatten nur einmal kurz angeschnitten das ein Interface auch was abstractes ist, meine ich, aber mehr wurd in der vorlesung leider noch nicht erwähnt


----------



## I2oxxi (7. Dezember 2011)

also soweit ich das jetzt verstanden habe ist das interface zur vordefinierung von methoden, die später erst einen inhalt bekommen?
Kannst du mir vielleicht noch einen denkanstoß geben?
was genau muss ich machen? habe mir jetzt gedacht ich definiere dann in dem interface die klassen vor  aber das hat mir auch nicht wirklich geholfen


----------



## I2oxxi (8. Dezember 2011)

Ok habe es jetzte geschafft  läuft alles super, er zählt die Wiederstände jetzt auch richtig, danke für den tipp:

Myinterface

```
package resistor;

public interface myinterface {
	
	public double ohm();
	public int countresistors();
	

}
```

Modellierung

```
package resistor;

import java.util.ArrayList;

public class modellierung  {

	
	
	public static void main(String[] args)
	{
	
		resistor r1=new resistor(100);
		resistor r2=new resistor(200);
		resistor r3=new resistor(300);
		resistor r4=new resistor(400);
		resistor r5=new resistor(500);
		resistor r6=new resistor(600);
		
		
		
		serial s1 = new serial(r4,r5);
		
		parallel p1 = new parallel (r1,r3);
		
		serial s2 = new serial(p1,r2);
		
		ArrayList<myinterface> a1 = new ArrayList<myinterface>();
		a1.add(s1);
		a1.add(s2);
		a1.add(r6);
		
		parallel p2 = new parallel(a1);
		
		System.out.println("Wiederstandswert : "+p2.ohm()+" Ohm");
		System.out.println("Resistoranzahl : "+p2.countresistors());
		
		
		
		
	
		
	}
}
```


In den Klassen selber hab ich halt nur beim Typ der ArrayList und diese Resistor netz1/2 Elemente auf myinterface geändert.
Nun, es klappt zwar, aber verstehen tu ich das ganze nicht so wirklich, wieso kann ich durch vordeklarieren der 2 Methoden auf einmal den Typ myinterface nehmen? grade habe ich das problem, das myinterface ja selber nichts von resistor/serial/parallel kennt. 
mein ansatz:
Ich denke mir das so, das halt die methoden im interface vordeklariert werden, und  dann alle objekte die ich dort hinein packe dann ohm() und counteresistors() ausführen können?
Und gültige objekte für die ArrayList<myinterface> sind alle objekte aus klassen die dieses Interface implementieren?
Oder wie soll ich das verstehen?
hatte leider vorher noch nie was mit interfaces zu tun, bin neu in java


//edit: hm, wie heute erfahren hätte ich das wohl alles über meine abstracte basisklasse netz laufen lassen können ....
ich muss mich wohl nochmal richtig dahinter setzen was abstracte klassen genau bedeuten und was man alles mit denen anstellen kann ...


----------



## Akeshihiro (8. Dezember 2011)

Das alles hat eigentlich nur mit Vererbung und Polymorphismus zu tun. Wenn du die beiden Sachen erst einmal verstanden hast, dann wirst du merken, dass das alles gar nicht so kompliziert ist.

Ach und Klassen und Co. fangen immer noch mit einem Großbuchstaben an


----------



## I2oxxi (9. Dezember 2011)

naja, ich hatte noch nie was mit dem ganzen abstrakten zeugs zu tun, muss mich da erst reinarbeiten ^^
ich hab jetzt schon mal die funktion von denen verstanden, aber ein paar fragen bleiben immernoch offen ...

z.B. hab ich jetzt ne neue aufgabe, da hab ich SuperMario in 3 formen also abstract mario und 3 unterklassen, alle können sich ducken, aber nur, wenn sie groß sind.
das ist dann halt in boolean istgroß
mein problem: definiere ich diese boolean instanzvariable jetzt in allen 4 klassen, oder nur in der oberklasse?
die methode macht ja in allen das gleiche, aber fragt diese variable ab, daher muss die variable ja auch in die abstracte klasse, oder?

und: alle haben auch die instanzvariable leben, welche für keine methoden vrwendet werden, nur der konstruktor setzt diese.
diese wird dann nur in den unterklassen aber nicht in der oberklasse eingeführt, richtig?




//Edit: Ich habe die vermutung, das ich diese ducken methode dann auch als abstract gestalten muss und später wo auch die instanz vorhanden ist erst definiere, richtig?


----------



## Akeshihiro (9. Dezember 2011)

Kannst du vielleicht noch die Aufgabe posten? Dann kann man da vielleicht näher drauf eingehen.

So wie ich dich bis jetzt verstanden habe, werden die drei konkreten Mario-Klassen wahrscheinlich die unterschiedlichen Typen darstellen, z.B. den normalen Mario und den spukenden Mario. Aber alle haben die gleiche Basis, lediglich die Fähigkeiten sind unterschiedlich, daher bietet sich für die Basis auch eine abstrakte Klasse an.

Die Methode _ducken()_ würde ich bereits in der abstrakten Klasse voll ausimplementieren, da das immer gleich ist. Bringt also nix, die Method abstrakt bereit zu stellen und nachher in den abgeleiteten Klassen mehrmals auf die selbe Weise zu implementieren (_"Don't repeat yourself"_). Das Gleich gilt auch für die Sache mit dem Leben. Gleich in die abstrakte Klasse rein und auch den Konstruktor bereits entsprechend implementieren. Wenn du nicht explizit den Default-Konstruktor (der mit der leeren Parameterliste) implementierst, dann müssen alle abgeleiteten Klassen den Konstruktor genauso implementieren.

Wie gesagt, das ist das, was ich so verstanden habe. Wenn wir die Aufgabe kennen, kann man da vielleicht besser drauf eingehen.


----------



## Akeshihiro (9. Dezember 2011)

Du kannst keine Instanzen von abstrakten Klassen bilden, das ist richtig. Dennoch kannst du in einer abstrakten Klasse Konstruktoren deklarieren.

EDIT:
Eine sehr schöne Aufgabe ^^ Werd ich spaßeshalber auch mal machen.

Wie gesagt, das Ducken, Rennen, Springen, die Größe und die Anzahl Leben kannst du getrost in _AbstrakterMario_ deklarieren und auch ausimplementieren. Beim _FlugMario_ ist das Sprungverhalten zwar anders, aber das stört nicht, dann wird seine Sprungmethode einfach überlagert (überschrieben) und schon macht er, was er soll. Gäbe es insgesammt nur zwei Marios, dann hätte man die Sprungmethode tatsächlich abstrakt deklarieren können und erst in der jeweiligen konkreten Klasse wirklich ausimplementiert. Da aber _SuperMario_ und _PinguinMario_ auf die gleiche Weise springen, ist das Käse. Das Gleiche ist auch beim Konstruktor. Alle Marios sollen die Größe und die Leben erhalten, der _FlugMario_ aber noch die Flugzeit als Zusatz. Das heißt, da kannst du auch locker in _AbstrakterMario_ den Konstruktor mit den beiden Parametern Größe und Leben implementieren und _FlugMario_ bekommt dann einfach einen neuen Konstruktor mit drei Parametern. Da ich aber vorhin gesagt habe, dass man einen Konstruktor auch in den abgeleiteten Klassen implementieren muss, hätten wir dann ja ein Problem. Bei _SuperMario_ und _PinguinMario_ passiert soweit nix, die bekommen einfach einen entsprechenden Konstruktor und rufen den Konstruktor von _AbstrakterMario_ mit _super(groesse, leben)_ auf. Beim _FlugMario_ ist das aber anders, denn er soll ja einen Konstruktor mit drei Parametern bekommen. Aber das ist nicht schlimm, dennoch kannst du auch da einfach den Konstruktor von _AbstrakterMario_ aufrufen, genau wie bei den anderen Marios, setzt noch die Flugdauer (dafür entsprechend dann ein neues Attribut deklarieren) und schon hat sich das auch erledigt.

Das Sammeln der Gegenstände kann scheinbar auch direkt in _AbstrakterMario_ rein. Nur das Werfen der Panzer macht mir grad Kopfschmerzen. Eigentlich ist das kein Problem, die Frage ist nur, wie man das am sinnigsten Umsetzt.

Naja, jedenfalls solltest du damit eigentlich ganz gut klar kommen, habs ja denke ich ausführlich erklärt ^^ Also dann viel Spaß bei der Aufgabe, sollte ja jetzt nicht so schwer sein.

Übrigens hätte ich persönlich _SuperMario_ als Basis für die anderen Marios genommen, das _SuperMario_ nunmal der Basis-Mario ist. Warum da extra ne abstrakte Klasse gebastelt werden soll, hab ich nicht ganz verstanden. Ist vermutlich für den Lernzweck gedacht, anders kann ichs mir nich erklären.


----------



## I2oxxi (9. Dezember 2011)

Ok, merk ich mir  Jetzt mal meine Kenntnisse testen:
Für meine Aufgabe kann ich die sache mit dem Konstruktor in der abstrakten klasse deklarieren aber nicht machen, da FlugMario eine andere Parameterliste hat, richtig?
Ich könnte den Konstruktor zwar überladen, aber es wäre weiterhin möglich, einen Flugmario ohne flugzeit zu erstellen, was aber nicht sein soll.
bzw müsste ich auch die flugzeit in die abstrakte klasse mi reinnehmen, was aber auch nicht darf. da die anderen Mario's keine flugzeit haben.

richtig? ^^

//Edit: ok alles klar, dann versuch ichs mal mit deiner erklärung das ich das alles in die abstrakte reintun. Das mit dem Konstruktor muss ich mir mal genau angucken, das mit dem panzer werfen hab ich schon ^^

//Edit2: und die gegenstände sollen auch wieder in ne extra abstrakte klasse rein.
und noch ne frage hab ich: habe das jetzt gemacht, mit dem konstruktor in der abstrakten klasse, aus welchem grund verlangen die unterklassen einen default konstruktor? 
public AMario(){};
wenn ich das nich mit drinn hab meckert eclipse rum

//Edit3: hm das werfen macht doch probleme ^^ pinguin mario soll ja keine panzer werfen und sammeln können, also kann ich schmeißen() nicht in die abstrakte mit rein nehmen, das PinguinMario nicht sammeln kann hab ich in der sammeln methode mit 

```
if(this.getClass()==PinguinMario.class)
			{
				System.out.println(this.getClass().getName() + " kann keine Panzer sammeln");
			}
			else
			{
				this.panzer++;
			}
```

gemacht .... aber da wertfen ja nicht in der abstrakten sein kann, hab ich ein problem


----------



## Akeshihiro (9. Dezember 2011)

Also es ist so: _AbstrakterMario_ hat ja jetzt keinen Default-Konstruktor, da du ja einen anderen Konstuktor explizit deklariert hast. Da die abgeleiteten Klassen in der in der Call-Hierarchie entsprechend einen Konstruktor der Vaterklasse aufrufen wollen und der Default-Konstruktor per Default auch nur den Default-Konstruktor der Vaterklasse aufruft, haben die Klassen jetzt ein Problem, denn es gibt diesen Default-Konstruktor nicht in _AbstrakterMario_ und somit weiß jetzt der Default-Konstruktor (z.B. von _SuperMario_) nicht, was er machen soll. Das heißt du musst jetzt auch in den abgeleiteten Klassen die entsprechenden Konstruktoren explizit implementieren, wobei das eigentlich eher egal ist, es geht nur um den Aufruf. Aber sinnvoller Weise würde es ja Sinn machen, wenn man die Konstruktoren auch mit sinnvollen Werten füttert und nich mit fiktivem Mist und diese Werte bekommst du eben durch einen entsprechenden Konstruktor.

So, jetzt könnte man sich natürlich fragen, warum dann überhaupt in _AbstrakterMario_ schon einen Konstruktor deklarieren, wenn ich in den Subklassen eh wieder die Konstruktoren deklarieren muss. Ganz einfach, weil die Konstruktoren der abgeleiteten Klassen anders aussehen. Die eigentliche Arbeit macht immer noch der Konstruktor von _AbstrakterMario_, die Konstruktoren der Subklassen leiten den Aufruf nur weiter, haben aber an sich keinen sinnvollen Code (außer _FlugMario_, da er ja noch die Flugzeit bekommt).

Das sieht dann so aus:

```
public class SuperMario extends AbstrakterMario {
	public SuperMario(boolean gross, int leben) {
		super(gross, leben);
	}
}
```

Das ist der ganze Trick dabei. Bei _FlugMario_ sieht der Konstruktor dann etwas anders aus, weil er noch einen weiteren Parameter hat. Aber auch da wird einfach per _super()_ der Vaterkonstruktor aufgerufen, nur musst du dann halt noch das mit der Flugzeit managen.


----------



## I2oxxi (9. Dezember 2011)

kann es dann sein, das wenn KEIN konstruktor vorhanden ist, im hintergrund default konstruktor aber da ist, aber sobald ich einen konstruktor schreibe, dieser nicht mehr da ist?
weil diese fehlermeldung kam halt sobald ich in der abstrakten klasse nen konstruktor mit reingenommen hab.

ja das mit dem super() hab ich schon grad rausgefunden, das ist echt ne toll mit dem super().
für flugmario hab ich

```
public FlugMario(boolean größe, int leben,int flugzeit)
	{
		super(größe,leben);
		this.flugzeit=flugzeit;
	}
```


Nur beim werfen häng ich jetz grade, aber das schaff ich au noch, dann hab ichs fertig


----------



## Akeshihiro (9. Dezember 2011)

Ja, genau so ist es auch. Wenn du keinen Konstruktor deklarierst, dann übernimmt das Java und deklariert selbst einen Default-Konstruktor. Der macht einfach nix, aber man braucht eben immer einen Konstruktor, wenn man man von Klassen Instanzen erzeugen will. Sobald du aber explizit einen Konstruktor deklarierst, deklariert Java keinen Default-Konstruktor mehr. Macht ja auch Sinn, denn es kann ja sein, dass man gar nicht will, dass man eine Instanz der Klasse über den Default-Konstruktor erzeugen will, sondern dass immer ein ganz bestimmter Parameter übergeben werden muss. Das ist also schon gewollt so.

EDIT:
Ja, an dem Werfen überlege ich auch grad. Mir fallen spontan drei Möglichkeiten ein, wie man das umsetzen kann. Die Frage ist, auf welche Weise es "besser" ist, wobei das eigentlich eher uninteressant ist. Viel mehr würde mich interessieren, was sich dein Prof bei der Aufgabe gedacht hat. Er wird ja eine Vorstellung davon gehabt haben und somit auch eine Beispiellösung parat haben. Die Frage ist also, in welche Richtung diese geht.


----------



## I2oxxi (9. Dezember 2011)

Ok, dann danke ich dir mal für deine erklärungen 
aber mit dem werfen komm ich nicht voran ... kann die werfen methode ja nicht in die abstrakte reintun, weil der pinguin diese nicht kennen darf. 
gleichzeitig ist aber in der abstrakten methode die sammeln methode drin, welche die panzeranzahl verwaltet.
so kann ich, wenn ich werfen() in die unterklasse tu, nicht auf die panzerzahl zugreifen ... 
mache ich nun aber beide methoden abstract, und implementiere diese später, musste ich wieder instanzvariablen leben und größe in die unterklasse mit aufnehmen, da wenn ein grüner/roter pilz gesammelt wird sich diese variablen verändern.....


//Edit: hm, habs jetz am laufen, hab das sammeln/werfen mit in der abstrakten klasse und hab dann in den methoden mit na if abfrage den fall das es auf ein pinguin objekt ausgeführt wird ausgeschlossen .... aber der sinn der sache ist das glaub ich nicht ^^

Lösung bekomme ich erst nächsten freitag.
Also wir haben grade als thema halt abstrakte klassen, polymorphismus, interfaces. grade angefangen. und nach den erklärungen vom prof hin, darf die nach diesem beispiel die klasse pinguinmario die funktion werfen auf keinen fall kennen, was meine jetzige lösung ja zunicht macht


----------



## Akeshihiro (9. Dezember 2011)

Ich habe das mit dem Werfen noch nich gemacht, aber kann dir ja mal meine Ideen verraten.

1. Man nimmt die Methode _werfen()_ mit in _AbstrakterMario_ auf und implementiert sie sogar aus, da _SuperMario_ und _FlugMario_ die Panzer ja werfen können. Bei _PinguinMario_ wird die Methode dann überlagert, allerdings mit einem leeren Methodenkörper, sprich sie macht nix. Aber da ist das Problem, das du bereits erkannt hast. Ich habe die Aufgabe auch so verstanden, dass _PinguinMario_ die Methode gar nicht kennen darf, das wäre aber bei diesem Ansatz der Fall.

2. Man bastelt sich ein Interface _Werfen_ oder so, das die Methode _werfen()_ deklariert. Das Interface wird von _SuperMario_ und _FlugMario_ implementiert und somit auch die Methode _werfen()_. Auf das Interface kann man eigentlich auch verzichten, aber so hat man es einheitlich und könnte dann sogar über das Interface agieren ohne zu wissen, welcher Mario-Typ da eigentlich verwendet wird.

3. Ist eigentlich wie 2, aber anstatt eines Interfaces wird jetzt eine weitere abstrakte Klasse _WerfenderMario_ deklariert, welche die Methode _werfen()_ deklariert und sogar implementiert. Die Klasse wird von _AbstrakterMario_ abgeleitet und _SuperMario_ und _FlugMario_ wiederum leiten von _WerfenderMario_ ab. Die Klasse _WerfenderMario_ ist deswegen abstrakt, weil sie nicht zur Instanziirung gedacht ist, sondern nur eine Schnittstellenfunktion erfüllen soll und somit die ableitenden Klassen nur um weitere Funktionalitäten erweitert.

Die sauberen Lösungsansätze sind 2. und 3., da 1. eher gepfuscht ist und laut Aufgabenstellung meiner Meinung nach die Aufgabe auch nicht erfüllt ist. Durch die Ansätze 2. und 3. ist gegeben, dass _PinguinMario_ die Methode _werfen()_ nicht kennt, die anderen beiden Marios aber schon (wie es nach meinem Verständnis in der Aufgabe gefordert ist). Im Ansatz 2. verändert sich an der ursprünglichen Umsetzung (also ohne Ansatz 1.) eigentlich soweit nichts, es kommt nur ein Interface hinzu. Beim Ansatz 3. wird die Vererbungshierarchie etwas abgeändert, indem _WerfenderMario_ mitten in die Hierarchie eingehangen wird. In der Aufgabe stand nichts davon, dass sowas verboten sei, müsste also erlaubt sein und wäre sogar die beste Umsetzung. Allerdings stört mich an der Variante etwas, ich weiß gerade nur nicht was ...


----------



## I2oxxi (12. Dezember 2011)

ich werd wenn ich die lösung bekomme diese heir mal posten, dann kanns du dir angucken wie er sich das vorgestellt hat. an ein interface hab ich auch schon gedacht, aber letzte mal war mein interface auch nur "unnötig" und "nicht gefordert" ...

Edit: 
Ich habe mich deiner dritten lösung mal angenommen:

aus AMario hab ich die private int panzer und die methode schmeißen rausgenommen, die sammeln method etwas modifiziert:

```
public void sammeln(AGegenstand gegenstand)
	{
		if(gegenstand.getClass()==RoterPilz.class)
		{
			this.größe=true;
			System.out.println(this.getClass().getName() + " wächst");
		}
		else if(gegenstand.getClass()==GrünerPilz.class)
		{
			this.leben++;
			System.out.println(this.getClass().getName() + " erhält ein Leben");
		}
	}
```
das hier ein else if ist ist gewwollt. der gegenstand könnte ja auch panzer sein. das wird heir aber noch nicht geprüft, dazu später mehr.


dann habe ich die abstrakte klassse ASchmeißenderMario, wenn ich das mit dem super richtig verstanden hab wird meine sammeln methode hier in der art erweitert?:

```
public abstract class ASchmeißenderMario extends AMario{
	
	private int panzer;
	
	public void schmeißen()
	{
		System.out.println(this.getClass().getName() + " wirft einen Panzer");
		this.panzer--;	
	}
	
		public void sammeln(AGegenstand gegenstand)
	{
		super.sammeln(gegenstand);
		if(gegenstand.getClass()==Panzer.class)
		{
			if(this.panzer<3)
			{
				System.out.println(this.getClass().getName() + " sammelt einen Panzer");
				this.panzer++;
			}
			else
			{
				System.out.println(this.getClass().getName() + " hat schon 3 Panzer");

			}
		}

	}
```
hier wird dann auch auf panzer geprüft

Das sollte soweit meiner Meinung nach alles ok sein.
Jetzt leitet sich ja die abstrakte klasse ASchmeißenderMario von AMario ab, die kenns du ja insoweit schon. 
Da ich mit dem super so noch keinen kontakt hatte habe ich jetzt ein kleines problem :
Du hast mir ja sowas hier gezeigt:

```
public class Mario extends ASchmeißenderMario{
	

	public Mario(boolean größe, int leben)
	{
		super(größe,leben);
	}
```

jetzt ist Mario ja aber in der ableitungsherachie weiter unten, ASchemißenderMario hat keine instanzvariablen außer dem panzer, daher könnte ich dort diesen konstruktor ja nicht vordefinieren, weshalb ich auch auf AMario weiter zugreifen muss.
Aber wie? Ich dachte jetzt an sowas wie super.super(größe,leben) oder super (super(größe,leben)) aber das ist wohl nicht die richtige syntax, falls sowas in der art möglich ist .. ^^



Edit 2:
Ok, musste in ASchmeißenderMario auch noch 

```
public ASchmeißenderMario(){};
	
	public ASchmeißenderMario(boolean größe, int leben)
	{
		super(größe,leben);
	}
```
einfügen .... hat sich also erledigt 

 Könntest mir nur gerne noch bestätigen das das mit dem sammeln in AWerfenderMario mit dem super so richtig ist, also ich denke, das die methode mit gleichem parameter halt erst auf roter pilz oder grüner pilz prüft, wie in der superklasse halt die sammelmethode ist, und danach noch was zusätzliches ausgeführt wird, halt das prüfen auf einen panzer, was aber halt durch die vererbungsherachie nur in Mario/Flugmario getan wird.


Hm ... Wenn ich mir meine eigenen texte hier so durchlese kann ich ziemlich schlecht im bezug auf programmierung erklären was ich meine xd


----------



## Akeshihiro (12. Dezember 2011)

Doch doch, das ist richtig so ^^ Zuerst wird die Original-Methode ausgeführt und dann dein dazugebastelter Teil.

Sorry, aber ich kann grad nicht so wirklich viel erklären oder helfen, hab mir meine linke Hand verbrüht und das tut höllisch weh, daher ist das jetzt auch nur so kurz.


----------

