Problem mit ArrayList - Typen innerhalb der ArrayList

I2oxxi

Mitglied
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
Code:
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
Code:
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)
Code:
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 ^^
 
Zuletzt bearbeitet:
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
 
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
 
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
 
Ok habe es jetzte geschafft :D läuft alles super, er zählt die Wiederstände jetzt auch richtig, danke für den tipp:

Myinterface
Code:
package resistor;

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

}

Modellierung
Code:
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 ...
 
Zuletzt bearbeitet:
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 ;)
 
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?
 
Zuletzt bearbeitet:
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.
 
Zuletzt bearbeitet:
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.
 
Zuletzt bearbeitet:
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
Code:
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
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück