Objekte klonen und Deep Copy

Schwupsi

Aktives Mitglied
Hi Leute!

Zur Übung soll ich eine Subklasse von "Vector" erzeugen, ich nenne sie "DeepCopy" und soll darin die geerbte add()-Methode überschreiben und entsprechend implementieren. Habe in der Klasse Vector nachgeschaut und habe gesehen dass diese Methode einen boolean zurückgibt. Warum? Sollte sie nicht void sein und einfach ein Object in die Collection "adden" (add-Methode) und nichts zurückgeben?

Die Aufgabe:
"Überschreiben Sie in DeepCopy die geerbte Methode add(Object), so dass das angegebene „Object“ dem DeepCopy nur hinzugefügt wird, wenn es ein Object der Klasse "X" oder "Y" ist und nicht von anderen."

Und wie sieht dann der Code in der add()-Methode aus? Habe hier keinen Ansatz zustande bekommen, mich irritiert das boolean. Hätte hier evtl. mit instanceof geprüft aber scheint mir zu schwammig..
Hoffe auf hilfreiche Tipps, Gruß!
 
Danke für die Antwort.

Habe das jetzt so gelöst:
Nehmen wir an die Collection soll nur Objekte der Klassen X und Y aufnehmen.
Java:
public boolean add(Object object){
if(object instanceof X){
return true;
}
if(object instanceof Y){
return true;
}
return false;
}

Das wäre mein Ansatz.. Wenn ich dann in der main() 2 Objekte adde und dann .get(0) und .get(1) mache kommt eine Exception, da nichts geaddet wurde. Ich denke, das liegt an der add() Methode, aber ich bin da etwas überfordert was den Code angeht, bisher waren die add() Methoden immer vorgegeben von der Superklasse und jetzt muss ich eine selbst schreiben, verstehe das nicht so ganz.
 
da deine add methode das objekt auch hinzufügen soll, muss es natürlich in deine add methode.
super.add ruft dann die add methode der elternklasse auf
 
Habe wieder ein kleines Problem. Ich habe eine Collection-Klasse "HuehnerHof" erstellt die von ArrayList erbt, und in der ich die add() Methode so überschreiben soll, dass keine doppelten Einträge möglich sind. Wie sieht da die if-Bedingung aus? :/
Habe erstmal ohne die if-Bedingung weitergemacht...

In einer anderen Test-Klasse habe ich davon eine Collection angelegt, die nur bestimmte Objekte annimmt.

HuehnerHof<Henne> hhof = new HuehnerHof<Henne>();

Habe dann in einer for-Schleife einige Objekte geaddet und soll dann mittels einer foreach Schleife prüfen ob es sich bei den Objekten um Objekte von "Henne" handelt.
Die einzig mögliche Version, bei allen anderen spackt der Compiler rum:
for(Object a : hhof){ <------ Fehler
assertTrue(a instanceof Henne);
}

Eigentlich richtig, oder? Wenn ich den Code ausführe zeigt er mir in der Zeile "for(Object a:hhof)" den Fehler
 
Es gibt eine Klasse "Henne" und eine Klasse "Ei".

Ei hat einen Konstruktor der zwei Werte erwartet. Henne hat einen Konstruktor der einen Wert und ein Ei-Objekt erwartet.

Java:
String name;
Ei ei;

Henne(String name, Ei ei){
this.name = name;
this.ei = ei;
}

String farbe;
double groesse;

Ei(String farbe, double groesse){
this.farbe = farbe;
this.groesse = groesse;
}

Also hat das Henne-Objekt quasi ein Ei.

Ich soll dann in der Klasse "Test" mehrere Hennen erzeugen (mit Ei), in eine Collection (Klasse "HuehnerHof") adden,
Java:
public class HuehnerHof<T> extends ArrayList implements Collection, Set{

@Override
public boolean add(Object obj){
if(this.contains(obj)){
return false;
}else{
super.add(obj);
return true;
}

}


}





und danach mit einer foreach-Schleife nacheinander prüfen, ob es sich um das jeweilige Objekt in der Collection tatsächlich um eine "Henne" handelt.

Java:
public void testHuehner(){
HuehnerHof<Henne> hhof = new HuehnerHof<Henne>();
for(int i = 0; i < 101; i++){
hhof.add(new Henne("Henne"+i; new Ei("blau", i)));
}

for(Object a : hhof){
assertTrue(a instanceof Henne);
}

}

Entweder ich hab foreach nicht verstanden oder der Fehler liegt woanders.
 
Zuletzt bearbeitet:
erstmal, HuehnerHof ist generisch und sollte den generischen Parameter auch weitergeben: extends ArrayList<T>

Ansonsten hast du nen syntaxfehler: hhof.add(new Henne("Henne"+i;new Ei("blau", i)));
anstatt einem komma hast du bei den Parametern ein Semikolon geschrieben
 
erstmal, HuehnerHof ist generisch und sollte den generischen Parameter auch weitergeben: extends ArrayList<T>

Ansonsten hast du nen syntaxfehler: hhof.add(new Henne("Henne"+i;new Ei("blau", i)));
anstatt einem komma hast du bei den Parametern ein Semikolon geschrieben

Das mit dem Syntaxfehler war ein Fehler meinerseits, beim Schreiben des Codes in diesem Beitrag. Das Original ist selbstverständlich ein Komma, statt Semikolon, aber danke! 🙂

Wenn ich "ArrayList<T>" setze, dann zeigt Eclipse einen Fehler in der add() Methode von HuehnerHof:
"The method add(T) in the type ArrayList<T> is not applicable for the arguments (Object)"

Java:
    @Override
    public boolean add(Object obj) {
        if(this.contains(obj)){
            return false;
        }else{
            super.add(obj);
            return true;
        }
    }

Java:
public class HuehnerHof<T> extends ArrayList<T> implements Collection, Set


Und HuehnerHof ist unterstrichen und zeigt folgendes:
"The interface Collection cannot be implemented more than once with different arguments: Collection<T> and Collection"

Bin echt verzweifelt, mich nervt das total, da fixt man das eine Problem und irgendwo wartet schon das nächste.. :/
 
wenn du den generischen Typen an ArrayList weitergibst, dann weiß Java, dass du eben nicht Object, sondern T als Typen verwenden möchtest, dadurch verlangt die add Methode auch nicht mehr nur Object, sondern den Typen T. Bei collection und set solltest du den Typen auch mitgeben
 
Ok, verstanden soweit. Habe jetzt auch Collection und Set den generischen Typen <T> mitgegeben. Jetzt ist der Aufruf der add() Methode der Superklasse rot unterstrichen "super.add(object);"

Hier bietet mir Eclipse zwei Fixes an:
Cast zu T -> "super.add((T) object);"
oder statt add(Object object) -> add(T object)

Kann mir aber kaum vorstellen, dass T richtig sein soll 😀
 
Schau dir am besten mal das Thema generische Typen nochmal an.

Die add Methode ist in ArrayList wie folgt definiert:
Java:
public boolean add(T obj) {
...
}
Dementsprechend musst du bei dir auch das T angeben.
 
Edit: mit T zeigt er zwar keine Compile-Fehler mehr an, aber es hakt trotzdem immer noch an der foreach Schleife, warum? Werde mich dann mal in generische Typen einlesen, wenn ich Zeit habe. Aber kann mir mal jemand sagen wie ich das ganze verdammte Ding zum Laufen kriege? 😀

Java:
public void testHuehner(){
HuehnerHof<Henne> hhof = new HuehnerHof<Henne>();
for(int i = 0; i < 101; i++){
hhof.add(new Henne("Henne"+i; new Ei("blau", i)));
}

for(Object a : hhof){
assertTrue(a instanceof Henne);
}

}
 
was genau hakt denn? Eine genauere Fehlerbeschreibung wäre gut^^
Ansonsten hier mal ein minimal Beispiel, was wunderbar funktioniert:
Java:
class HuenerHof<T> extends ArrayList<T> { }
Java:
HuenerHof<Henne> h = new HuenerHof<Henne>();
h.add(...);
h.add(...);
for(Henne henne : h) {
  System.out.println(henne);
}
 
was genau hakt denn? Eine genauere Fehlerbeschreibung wäre gut^^
Ansonsten hier mal ein minimal Beispiel, was wunderbar funktioniert:
Java:
class HuenerHof<T> extends ArrayList<T> { }
Java:
HuenerHof<Henne> h = new HuenerHof<Henne>();
h.add(...);
h.add(...);
for(Henne henne : h) {
  System.out.println(henne);
}

Er zeigt mir in der Zeile:
Java:
for(Henne henne : h)
eine NullPointerException.

Wenn ich das richtig verstanden habe, heißt das, dass der Iterator an der Stelle 0 ein null-Objekt vorfindet oder?
Aber ich habe vorher mit einer for-Schleife 100 Objekte erzeugt und der Collection bzw. der ArrayList geaddet.
 
am besten solltest du den StackTrace posten.
Entweder ist halt dein HuenerHof null oder beim iterator ist irgendwas null.
Der StackTrace gibt da mehr auskunft
 
java.lang.NullPointerException
at ueb.huehner.TestHuehner.test101Hennen(TestHuehner.java:17)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at junit.framework.TestCase.runTest(TestCase.java:176)
at junit.framework.TestCase.runBare(TestCase.java:141)
at junit.framework.TestResult$1.protect(TestResult.java:122)
at junit.framework.TestResult.runProtected(TestResult.java:142)
at junit.framework.TestResult.run(TestResult.java:125)
at junit.framework.TestCase.run(TestCase.java:129)
at junit.framework.TestSuite.runTest(TestSuite.java:255)
at junit.framework.TestSuite.run(TestSuite.java:250)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:131)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
 
Java:
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;

public class HuehnerHof<T> extends ArrayList<T> implements Collection<T>, Set<T> {

    @Override
    public boolean add(T obj) {
        if(this.contains(obj)){
            return false;
        }else{
            super.add(obj);
            return true;
        }
    }


Der Konstruktor von "Henne" erwartet einen (String) Namen und ein Objekt Ei.
Der Konstruktor von "Ei" erwartet eine (String) Farbe und eine Größe (double)
Java:
import junit.framework.TestCase;



public class TestHuehner extends TestCase{
 
    public void testHennen(){
        HuehnerHof<Henne> hhof = new HuehnerHof<Henne>();
        for(int i = 0; i<101; i++){
            hhof.add(new Henne("Henne"+i, new Ei("blau", i)));
        }
        try{
            for(Henne h : hhof){
                System.out.println(h);
            }
            }catch(Exception e){
                e.printStackTrace();
            }
    }
 
der Code funktioniert so bei mir Einwandfrei

Dein Ernst? Oh man.. bei mir ist der JUnit Test zwar erfolgreich, aber dennoch zeigt er eine NullPointerException, fuck...

Wenn ich ganz normal statt der foreach Schleife, eine for-Schleife durchlaufen lasse mit System.out.println(hhof.get(x)); dann gibt er mir alle Objekte aus.. seltsam
 
Zuletzt bearbeitet:

Zurück
Oben