PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [JAVA] Objekt-Kopie anlegen mit Referenz einer abstrakten Klasse


Nasenbaer
2008-05-24, 22:14:06
Angenommen habe eine Klasse XY, die als member eine Objekt referenz vom Typ einer abtrakten klasse hat:


class XY
{
private AMyClass m_AMyClass;
// ...
}

public abstract class AMyClass
{
public AMyClass(AMyClass class)
{
// kopiere member werte.
}
// ...
}

public class MyClass()
{
// ...
}


Nunn will ich eine Methode XY.getAMyClass() schreiben, die statt der eigentlichen Referenz eine Kopie mittels des Copy-Contructors von AMyClass anlegt - also so:


class XY
{
public AMyClass getAMyClass()
{
return new AMyClass(m_AMyClass);
}
}


So würde es funktionieren, wenn AMyClass nicht abtrakt wäre aber das ist bei mir der Fall. Wie kann ich dennoch ne kopie anlegen?

Monger
2008-05-24, 22:34:56
Ich habs jetzt ehrlich gesagt nie ausprobiert, aber wo liegt das Problem?

Konstruktoren dürfen in einer abstrakten Klasse definiert werden. Selbstverständlich müssen sie von den erbenden Klassen richtig erfüllt werden - die Oberklasse sollte also geschickterweise sowas wie ein "NotSupportedException" o.ä. werfen, damit man auch wirklich angehalten ist, die Unterklassen richtig zu implementieren.

Nasenbaer
2008-05-24, 22:58:12
Ich habs jetzt ehrlich gesagt nie ausprobiert, aber wo liegt das Problem?

Konstruktoren dürfen in einer abstrakten Klasse definiert werden. Selbstverständlich müssen sie von den erbenden Klassen richtig erfüllt werden - die Oberklasse sollte also geschickterweise sowas wie ein "NotSupportedException" o.ä. werfen, damit man auch wirklich angehalten ist, die Unterklassen richtig zu implementieren.

Genau hier:

return new AMyClass(m_AMyClass);

Ich versuche eine abstrakte klasse zu instanzieren und das geht natürlich nicht.

Monger
2008-05-24, 23:16:48
Ja, jetzt langsam dämmerts mir. Ach wie doof... Konstruktoren sind ja nunmal Methoden der Klasse, und nicht des Objekts.

Das einfachste wäre es wohl, eine Methode wie Copy oder Clone zu implementieren. Nehmen wir also mal an, du hast ein Objekt:


AbstractThing t;

dann sieht der Kopieraufruf halt so aus:


AbstractThing newThing = t.clone();

Implizit kannst du darin immer noch den Copy Konstruktor der jeweiligen Klasse aufrufen (bietet sich vermutlich auch an, beides zu haben).

Man könnte sich natürlich auch erstmal über Reflections den Typ des jeweiligen Objekts raussuchen - und darauf dann eben den Copy Konstruktor aufrufen... scheint mir aber nicht gerade ein besonders schöner Weg zu sein.

Nasenbaer
2008-05-24, 23:42:53
Werd ich morgen früh gleich mal testen und dann bescheid geben obs geklappt hat.

Ectoplasma
2008-05-25, 10:37:20
Willst du eigentlich nur ein shallow copy oder ein deep copy machen? Letzteres muss man selbst implementieren.

Hardwaretoaster
2008-05-25, 11:24:00
Wozu eigentlich MyClass (sehe ich oben nicht verwendet)? Ich hätte jetzt vermutet, dass du die Klasse von der abstrakten AMyClass erben lässt.
Wenn du diese implementierst, kannst u ja davon ein Objekt erzeugen lassen.
Oder bin ich auch dem falschen Dampfer.

Nasenbaer
2008-05-25, 16:35:03
@Hardwaretoaster
Ja so war es gedacht:

class MyClass extends AMyClass
{ // ... }


Und da ich den Objekten vom Typ XY ja unterschiedliche Ableitungen von AMyClass unterschieben will kann ich ja nur den kleinsten gemeinsamen Nenner als member nutzen und der ist AMyClass.

@Ectoplasma
Prinzipiell ne deep copy, aber da die abgeleiteten Klassen (und die abstrakte auch) aber nur Werte vom Typ double enthalten, reicht shallow natürlich auch (was später manche abgeleiteten Klasse als member haben weiß ich ja jetzt noch nicht).

@Monger

Hat funktioniert. Die Abstrakte hat ne Methode public abstract AMyClass clone() und die konkreten dann eine entsprechende Implementation von clone():

class MyClass extends AMyClass
{
public MyClass(MyClass class)
{
// impelement copy constructor
}

public AMyClass clone()
{
return new MyClass(this);
}
}