Java Java zu Objekte und Verweisen untereinander

estre

Commander
Registriert
Dez. 2005
Beiträge
3.006
Hallo zusammen,

ich habe ein kleines Problem in Java, für das ich momentan keine schöne Lösung finde. Vielleicht könnt Ihr mir ja weiterhelfen.

Angenommen wir haben eine Klasse "Vater" und eine Klasse "Kind". Die Klasse Kind erbt von der Klasse "Vater", weil
jedes Kind irgendwann auch mal Vater sein kann :)

Das Problem ist nun folgendes:
Wenn ich jetzt ein Objekt der Klasse Vater erzeuge und anschließend x Objekte der Klasse Kinder (je nachdem wieviel Kinder der Vater hat, was per Zufall definiert wird), wie kann ich dann einen Verweis herstellen, dass die Kinder-Objekte zu dem gemeinsamen Vater-Objekt gehören?

Das Ziel ist am Ende folgende Ausgabe:
Code:
Vater1 hat folgende Kinder: Kind1, Kind2, Kind3
Vater2 hat folgende Kinder: Kind1, Kind2
Vater3 hat folgende Kinder: Kind2
usw.

Ich hoffe ihr versteht was ich meine ^^ ?!


Vielen Dank!
 
Jeder Vater wird wahrscheinlich eine Liste von Kindern aufweisen um dies abzubilden.
 
Ich weiß nicht, was du für einen Programmierbackground hast, aber deine Ausdrucksweise lässt darauf schließen, dass du entweder Anfänger bist oder von einer komplett anderen Sprache kommst.

Ich würde mal nach Objektvariablen in Java googlen. Das Geheimnis ist, dass Klassen Variablen vom Typ einer anderen Klasse haben können.

Code:
class Vater {
    String name;
    int alter;
    Kind kind;
}

somit kannst du im Code irgendwo ein Vater Objekt und ein Kind Objekt erzeugen und das Kind Objekt der Kind Variable im Vaterobjekt zuweisen.

Edit: Wie schon erwähnt, möchte man das ganze natürlich dynamisch halten, damit man einem Vater nachträglich Kinder hinzufügen kann. Also ist die Kind Variable eine Arraylist oder eine andere dynamische Datenstruktur.
 
Man sollte hier menschliche Vererbung und Objekt-Orientierte Vererbung nicht versuchen so genau zu verknüpfen ;) Ein Kind sollten nicht von einem Vater abgeleitet werden, eher würden beide von einem Objekt namens Mensch abgeleitet. Wenn diese sich nun aufgrund ihrer Verbindung verschiedene Eigenschaften teiloen (wie z.B. Nachname) könnte man im Constructor des Kindes den Vater einsetzen ala new Kind(vater,mutter) und in der Methode dann verschieden Variablen des Kindes automatisch mit Werten der Eltern füllen.
 
Es kommt auch drauf an was Du erreichen willst. Der Vater kann eine Liste von Kindern inne haben. Oder ein Kind ein Verweis auf den Vater. Oder beides.

Ansonsten hat Umbel natürlich recht. Tokolosh Beispiel ist eher ungünstig, weil ein Vater so nur ein Kind haben kann.
 
Ich wollte auch nicht alles gleich vorwegnehmen und nur mal die Idee von Objektvariablen demonstrieren. Habe den Beitrag schon mit dem Gedanken der Liste entsprechend editiert ;)

Der Einwand mit der Vererbung finde ich sehr sehr gut, das habe ich selbst total überlesen.
Es ist im allgemeinen Unlogisch, dass Kind von Vater erbt ...
 
Wie die Vorredner schon quasi gesagt haben gucke dir mal Informationen zu den Java Collections Framework an. Je nach Kontext sind unterschiedliche Datenstrukturen sinnvoll.

Kleiner Tipp: Teilweise lässt sich anhand der Umgangssprache auf die Klasse schließen nach der du suchst. Z.B. Liste -> List (Würde ich allerdings nur bei kleinen Projekten wie scheinbar deinem empfehlen)
 
Vielen Dank für die zahlreichen Antworten.

Umbel schrieb:
Man sollte hier menschliche Vererbung und Objekt-Orientierte Vererbung nicht versuchen so genau zu verknüpfen ;) Ein Kind sollten nicht von einem Vater abgeleitet werden, eher würden beide von einem Objekt namens Mensch abgeleitet. Wenn diese sich nun aufgrund ihrer Verbindung verschiedene Eigenschaften teiloen (wie z.B. Nachname) könnte man im Constructor des Kindes den Vater einsetzen ala new Kind(vater,mutter) und in der Methode dann verschieden Variablen des Kindes automatisch mit Werten der Eltern füllen.

Hier möchte ich noch einmal nachhaken:
Deinen Einwand, dass man hier Vater und Kind nicht über Vererbung verbinden kann/sollte verstehe ich nicht, was spricht dagegen?
Die Klasse Vater bekommt z.B. Eigenschaften, die das Kind (noch) nicht benötigt (z.B. Name der Ehefrau oder Steuerklasse).
Das Kind hingegen existiert ebenfalls als eigene Klasse und kann irgendwann mal auf Funktionen der Vater-Klasse zugreifen (wenn es im Kontext des Programmes Sinn macht) und sich seinerseits an dessen Funktionen bedienen.

Vom Aufbau macht das aus meiner Sicht durchaus Sinn. Wieso soll ich eine Mensch-Klasse anlegen, wenn ich diese nicht brauche...
 
Weil es beides primär Menschen sind und nicht Vater und Kind und wen du mal eine Tochter oder Frau brauchst müsstest du noch einmal zwei Klassen erstellen. Oder stell dir vor der Vater unterzieht sich einer Geschlechts Umwandlung und ist auf einmal Mutter.

Und zum Schluss Erbst du auch das Mensch und nicht das Vater sein...
 
ok, vielen Dank, habe ich verstanden.

Ich habe noch eine kurze Frage, die aber etwas vom Thema abweicht:

Ist es üblich/sauber programmiert wenn man in einer Klasse eine Liste anlegt, die wiederum Objekte der eigenen Klassen beinhaltet?

Beispiel
Code:
public class Roboter {
ArrayList<Roboter > R = new ArrayList<Roboter >();

public void erzeugeNachkommen(Roboter R){
		this.R.add(R);
	}


{

Ziel:
Ein Roboter wird geboren und nachdem er bestimmte Aufgaben erfüllt hat, darf er Nachkommen erzeugen.
Am Ende soll eine Liste mit allen Nachkommen des Roboters ausgegeben werden.
 
Zuletzt bearbeitet:
Ja gibt sehr häufig Klassen die einen Verweis auf ihre Kinder oder Eltern vom selben Typ haben.

Und was mir Grad noch zum eigentlichem Thema eingefallen ist im Prinzip ist der Vater ja selbst ein Kind was dazu führt das er von etwas Erben muss was Kind und Vater beinhaltet.
 
Bei solchen Listen ist aber auch Vorsicht geboten, weil du wild verteilt Referenzen auf Objekte hast, die möglicherweise gar nicht mehr von Programm gebraucht werden, jedoch nicht garbage collected werden können, eben weil du noch Referenzen festhältst. Abhilfe können da weak references schaffen, aber wie du hier lesen kannst, kommt es auf den Einzelfall an, ob das sinnvoll ist.

Alternativ kann man Listen von identifiern (z.B. ein id-Feld pro Instanz) halten, also eine Liste von Strings/longs. Dadurch hältst du keine Referenzen fest, musst aber eben einen HashMap-Loopkup beim Zugriff in Kauf nehmen. Das ist aber ziemlich performant und meiner Meinung nach zu bevorzugen. Du hättest in dem Fall nur eine zentrale Referenzliste aller Instanzen, für gewöhnlich eine HashMap, bei Multithreading eben eine ConcurrentHashMap.
 
Tumbleweed schrieb:
Alternativ kann man Listen von identifiern (z.B. ein id-Feld pro Instanz) halten, also eine Liste von Strings/longs. Dadurch hältst du keine Referenzen fest, musst aber eben einen HashMap-Loopkup beim Zugriff in Kauf nehmen. Das ist aber ziemlich performant und meiner Meinung nach zu bevorzugen. Du hättest in dem Fall nur eine zentrale Referenzliste aller Instanzen, für gewöhnlich eine HashMap, bei Multithreading eben eine ConcurrentHashMap.

Mir kommt es weniger auf Performance als auf saubere Codestruktur an, das ist die einzige Anforderung die ich habe.
Ist es denn auch üblich, dass das Objekt, das die Liste hält selbst auch in der Liste vorkommt, also quasi auf sich selbst zeigt?
In dem Beispiel wäre das dann:
Code:
R.add(R);

Anders bekomme ich das nicht umgesetzt, weil am Ende alle Familienmitglieder ausgegeben werden sollen, wo der "Urroboter" natürlich dazu gehört.
 
Mir fällt spontan kein sinnvoller Anwendungsfall dafür ein.

Für dein genanntes Beispiel würde ich vermutlich eine zentral gelegene Liste aller Familien anlegen. Ein Objekt der Klasse Familie hat dann eine übersichtliche Liste von ein paar Referenzen auf die Familienmitglieder. Das einzelne Familienmitglied braucht dann nur noch eine einzelne Referenz, nämlich die auf seine Familie. Auch das ist aber kein Muss. Je nach Anwendungsfall ist eine unidirektionale Relation ausreichend, d.h. es reicht, wenn man alle Familien nach einer bestimmten Person durchsuchen kann. Wenn man das oft macht oder es viele Familien gibt, dann ergibt so eine Rückreferenz natürlich Sinn.
 
Könnte in etwa so ausschauen ist nicht getestet und nur ein Beispiel.

Code:
class Robot
{
	private List<Robot> children;
	private Robot mother;
	private Robot father;
	private boolean  isMale;
	private String name;
 	
	public Robot(Robot _mother, Robot _father, String _name)
	{
		mother = _mother;
		father = _father;
		name = _name;

		children = new ArrayList<Robot>();
	}
	
	public void addChild(Robot _partner)
	{
		if(!isMale)
		{
			children.add(new Robot(this,_partner,"Anon Ymous"));
		}
		else
		{
			children.add(new Robot(_partner,this,"Anon Ymous"));
		}
	}
	
	public void showFammily()
	{
		if(mother != null && father != null)
		{
			System.out.println("Mother = " + mother.getName());
			System.out.println("Father = " + father.getName());

//			Unschöne Lösung für geschwister
//			for (Robot child : mother.getChildren()) 
//			{
//				if(child.getName() != this.name)
//				{
//					String type = "brother";
//					if(!child.getIsMale())
//						type = "sister";
//					System.out.println(type + " = " + child.getName());
//				}
//			}
			
		}
		else
		{
			System.out.println("No parents");
		}
		
		for (Robot child : children) 
		{
			System.out.println("Child = " + child.getName());
		}
	}
	
	public String getName(){return name;};
	public List<Robot> getChildren(){return children;};
}

Oder du machst noch einen Fammilien Manager wie von Tumbleweed empfohlen was an sich wohl auch die bessere Lösung wäre.
 
Tumbleweed schrieb:
Mir fällt spontan kein sinnvoller Anwendungsfall dafür ein.


Angenommen die Liste wird als statisches Attribut definiert, d.h. sie existiert auch unabhängig von den Objekten.
Wenn man dann alle Objekte dort reinpackt, dann wäre es wieder sauber, oder? Nach meinem Verständnis würde das Objekt dann nicht mehr auf sich selbst zeigen.
 
Dann würden sich alle die selbe Liste teilen und den static modifier solltest du in der Regel meiden.

Code:
         Robot robotA = new Robot();
         Robot robotB = new Robot();
         robotA.list.add(a);
         System.out.println(robotA.list.size());//verweis a
         System.out.println(robotB.list.size());//verweos b
         System.out.println(Robot.list.size());//hat die einzige "echte" liste

Du erzeugst zwar neue Roboter aber die einzige Liste ist die in der Klasse Robot.
 

Ähnliche Themen

Zurück
Oben