UML Diagramm

Snaer

Aktives Mitglied
Guten Tag,

Ich soll als Aufgabe dieses UML Diagramm in einen Code umsetzen.
Eigentlich dachte ich fertig zu sein jedoch bekomme ich folgende Fehlermeldung:

There was 1 failure:
1) test(PublicTests)
java.lang.AssertionError: expected:<2> but was:<0>
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.failNotEquals(Assert.java:834)
at org.junit.Assert.assertEquals(Assert.java:645)
at org.junit.Assert.assertEquals(Assert.java:631)


Mein Code sieht so aus :
Code:
import java.util.Date;

public class Gemaelde extends Kunstwerk implements Restaurierbar {
public Gemaelde(Kunstmuseum museum) {
        super(museum);
        // TODO Auto-generated constructor stub
    }

private Date zuletztRestauriertAm;

public void restaurieren() {
    
}

public Date getZuletztRestauriertAm() {
    return zuletztRestauriertAm;
}

public void setZuletztRestauriertAm(Date zuletztRestauriertAm) {
    this.zuletztRestauriertAm = zuletztRestauriertAm;
}
}

import java.util.ArrayList;


public class Kunstmuseum {
private ArrayList<Kunstwerk> werke = new ArrayList<Kunstwerk>();
private String name;

public ArrayList<Kunstwerk> getWerke(){
    return werke;
}
public void setWerke(ArrayList<Kunstwerk> werke) {
    this.werke=werke;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}


}


public abstract class Kunstwerk {
    private String name;
    private double preis;
    private Person besitzer;
    private Kunstmuseum museum;
    
    public Kunstmuseum getMuseum () {
        return this.museum;
    }
    public void setMuseum (Kunstmuseum museum) {
        this.museum=museum;
    }
    
    public Kunstwerk(Kunstmuseum museum) {
        if (museum == null) {
            throw new IllegalArgumentException();
        }
        this.setMuseum(museum);
    }
    
    public Person getBesitzer () {
        return besitzer;
    }
    
    public void setBesitzer (Person besitzer) {
        this.besitzer = besitzer;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getPreis() {
        return preis;
    }
    public void setPreis(double preis) {
        this.preis = preis;
    }

}

Das Problem ist, dass ich mir nichts genaueres unter dem Fehler vorstellen kann. Meine Vermutung ist bislang das es an Gemaelde und Statue liegt.
Für eine Erläuterung des Fehlers und Hinweise zur Lösung wäre ich sehr dankbar!
 

Anhänge

  • PMP_Ass08.pdf
    62 KB · Aufrufe: 21
K

kneitzel

Gast
Vermutlich hat der Test zwei Kunstwerke für ein Museum erzeugt und dann die Anzahl an Kunstwerken im Museum geprüft.

Nun kannst Du mal schauen, wieso die Anzahl an Kunstwerken 0 ist, wenn da doch zwei Kunstwerke erzeugt wurden.

Ansonsten wäre es sehr gut, wenn wir die Tests auch sehen könnten um zu sehen, was schief gelaufen ist. Das würde es deutlich vereinfachen...
 

Snaer

Aktives Mitglied
Mein Fehler ich vergaß dachte ich hätte an den Test gedacht.

Code:
import static org.junit.Assert.*;

import java.util.Date;

import org.junit.Test;

public class PublicTests {

    @Test
    public void test() {
        Kunstmuseum kunstmuseum = new Kunstmuseum();
        kunstmuseum.setName("Koblenzer Kunstmuseum");
        assertEquals("Koblenzer Kunstmuseum", kunstmuseum.getName());
        assertNotNull(kunstmuseum.getWerke());
        assertEquals(0, kunstmuseum.getWerke().size());
        
        Kunstwerk kunstwerk1 = new Statue(kunstmuseum);
        Kunstwerk kunstwerk2 = new Gemaelde(kunstmuseum);
        assertEquals(kunstmuseum, kunstwerk1.getMuseum());
        assertEquals(kunstmuseum, kunstwerk2.getMuseum());
        
        assertEquals(2, kunstmuseum.getWerke().size());
        
        kunstwerk1.setName("Werk1");
        kunstwerk1.setPreis(499.99);
        kunstwerk2.setName("Werk2");
        kunstwerk2.setPreis(349.99);
        assertEquals("Werk1", kunstwerk1.getName());
        assertEquals(499.99, kunstwerk1.getPreis(),1E-4);
        
        ((Statue)kunstwerk1).setHoehe(300);
        assertEquals(300,((Statue)kunstwerk1).getHoehe());
        
        Date date = new Date();
        ((Gemaelde)kunstwerk2).setZuletztRestauriertAm(date);
        assertEquals(date, ((Gemaelde)kunstwerk2).getZuletztRestauriertAm());
        assertTrue(kunstwerk2 instanceof Restaurierbar);
        ((Restaurierbar)kunstwerk2).restaurieren();
        
        Person person1 = new Person(kunstwerk1);
        assertEquals(person1, kunstwerk1.getBesitzer());
        person1.setName("Person1");
        assertEquals("Person1",person1.getName());
        assertEquals(1,person1.getKunstwerke().size());
        assertTrue(person1.getKunstwerke().contains(kunstwerk1));
    }

}

Der Test erzeugt in der Tat 2 Kunstwerke, jedoch verstehe ich nicht wieso das Ergebnis 0 sein soll.
Habe ich es richtig verstanden, dass assertEquals überprüft ob die beiden gleich sind?
 
K

kneitzel

Gast
Das Ergebnis soll nicht 0 sondern 2 sein. Der Test besagt ja:
assertEquals(2, kunstmuseum.getWerke().size());

Also 2 ist der Soll Wert und er fragt vom kunstmuseum getWerke().size() ab.

Und beim Ausführen meckert er, denn es soll 2 sein, aber es ist 0.

Und der Code, der ausgeführt wird, ist ja:
Java:
        Kunstwerk kunstwerk1 = new Statue(kunstmuseum);
        Kunstwerk kunstwerk2 = new Gemaelde(kunstmuseum);
==> Schau dir jetzt einfach den Konstruktor an. Was passiert da? Wird da das übergebene Museum irgendwo angepackt?
 

Snaer

Aktives Mitglied
Meine Aussage kam falsch rüber, ich meinte, weswegen es bei meinem Code 0 wird ^^.

An sich übergebe ich ja das museum in Statue und Gemaelde weiter bei
Code:
public Gemaelde(Kunstmuseum museum) {
        super(museum);
        // TODO Auto-generated constructor stub
    }

zum Beispiel.
Verstehe ich es richtig, dass ich das ich in dem Konstruktor dann noch etwas ändern muss bzw die Größe übergeben soll?
Bzw dass das Problem daran liegt, dass ich das museum zwar übergebe es jedoch nicht benutze?
 
K

kneitzel

Gast
Ja genau. Derzeit speicherst Du das Museum ja nur in deinem Kunstwerk. Dadurch kennt das Museum aber das Kunstwerk nicht. Somit musst Du mal schauen, wie Du ein Kunstwerk in einem Museum bekannt machen kannst.
 

Snaer

Aktives Mitglied
Okay danke für den Tipp!
Das werde ich morgen dann direkt mal ausprobieren mein Ansatz wäre es in Musuem ein Kunstwerk zu erstellen
Sprich private Kunstwerk kunstwerk;
 
K

kneitzel

Gast
Okay danke für den Tipp!
Das werde ich morgen dann direkt mal ausprobieren mein Ansatz wäre es in Musuem ein Kunstwerk zu erstellen
Sprich private Kunstwerk kunstwerk;
Du hast da doch schon eine Liste mit Kunstwerken:
private ArrayList<Kunstwerk> werke = new ArrayList<Kunstwerk>();
 

Snaer

Aktives Mitglied
Stimmt mein Fehler.
Mein Ansatz sieht nun so aus, leider kann ich diesen im Moment nicht testen, da die Seite nicht erreichbar ist.
Code:
import java.util.ArrayList;
import java.util.List;


public class Kunstmuseum {
private List<Kunstwerk> werke;
private String name;

 
public Kunstmuseum(String name) {
    this.werke= new ArrayList<Kunstwerk>();
    this.name=name;
}

public void addWerk (Kunstwerk werk) {
    this.werke.add(werk);
}
public void removeWerk(Kunstwerk werk) {
    this.werke.remove(werk);
}

public List<Kunstwerk> getWerke(){
    return this.werke;
}

public void setWerke(List<Kunstwerk> werke) {
    this.werke=werke;
}


public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

Ich habe mich viel dabei an einer Beispiel Folie orientiert, meine Intention dahinter war es die Kunstwerke auf die Liste überhaupt erst zu übertragen, da sie wenn ich es richtig verstanden hatte bis zum letzen Zeitpunkt zwar existierte jedoch noch leer war.
Bin ich damit zumindest auf den richtigen Weg oder denke ich völlig in die falsche Richtung?
 
K

kneitzel

Gast
Also das ist eine Änderung, die alleine nichts macht. Du hast neue Methoden, aber denn die nicht aufgerufen werden, dann bewirken sie nichts.

Manche IDEs zeigen das auch etwas an - meine IDE (IntelliJ) zeigt so Methoden grau an, da diese aus Sicht der IDE nicht benutzt werden.

Und da du an die werke ja schon über getWerke() heran gekommen bist, waren diese Methoden nicht notwendig (Wobei mir diese besser gefallen als Getter/Setter auf werke).

Du solltest also noch etwas anpassen so dass z.B. nach der folgenden Zeile Code:
Java:
Kunstwerk kunstwerk1 = new Statue(kunstmuseum);
die Statue auch in werke von kunstmuseum ist. Was wird da aufgerufen? An welchen Stellen könntest Du da etwas machen?
 

Snaer

Aktives Mitglied
Ich gehe davon aus, dass das Problem in der Klasse Kunstmuseum liegt, da du sagst, dass ich dafür sorgen muss das die Werke auch dort sind.
So wie ich es verstehe, korrigiere mich gerne wenn ich falsch liege, wird ein neues Kunstwerk Objekt erzeugt.
Würde es helfen eine Statue kunstmuseum in der Klasse zu intialisieren, damit die Klasse eben diese kennt oder ist das bei weitem zu einfach gedacht?
 

temi

Top Contributor
Ich gehe davon aus, dass das Problem in der Klasse Kunstmuseum liegt, da du sagst, dass ich dafür sorgen muss das die Werke auch dort sind.

Nein, Kunstmuseum hat ja eine sehr praktische Methode addWerk(), die du verwenden kannst.

So wie ich es verstehe, korrigiere mich gerne wenn ich falsch liege, wird ein neues Kunstwerk Objekt erzeugt.

Genau und diesem Kunstwerk wird ein Kunstmuseum mitgegeben (im Konstruktor). Mit dem Kunstmuseum kannst du doch was machen! **Wink mit dem Zaunpfahl**


Würde es helfen eine Statue kunstmuseum in der Klasse zu intialisieren, damit die Klasse eben diese kennt oder ist das bei weitem zu einfach gedacht?
Das verstehe ich nicht, was du da vorhast...
 

Snaer

Aktives Mitglied
Tut mir Leid wenn ich einen offensichtlichen Hinweis missinterpretiere :rolleyes:
Aber muss ich vielleicht dann in der Klasse Kunstwerk mittels Konstruktor den Namen des Museums mitgeben? Da dies ja der einzige Parameter in der Klasse Kunstmuseum ist und ich es so eventuell zu einem erzeugten Museum zuweisen kann.
 

temi

Top Contributor
Schau dir doch mal den Test an:
Java:
        Kunstwerk kunstwerk1 = new Statue(kunstmuseum);
        Kunstwerk kunstwerk2 = new Gemaelde(kunstmuseum);

Da werden zwei Kunstwerke erzeugt und die bekommen "ihr" Kunstmuseum im Konstruktor mitgegeben.

Ein Kunstwerk kann sich durchaus auch selbst "seinem" Museum hinzufügen: kunstmuseum.addKunstwerk(this);
 

Snaer

Aktives Mitglied
Mir fällt auf, dass ich in meinen Klassen Statue und Gemaelde ein "museum" im Konstruktor mitgebe anstelle eines kunstmuseum.
Ist das ein Fehler der mir Probleme bereitet?

Ansonsten stehe ich leider gerade echt auf dem Schlauch was ich mit dem besagten kunstmuseum, welches bei der Initialisierung im Test mitgegeben wird, tun kann.
 

temi

Top Contributor
Mir fällt auf, dass ich in meinen Klassen Statue und Gemaelde ein "museum" im Konstruktor mitgebe anstelle eines kunstmuseum.

Meinst du damit z.B. dieses?
Java:
public Gemaelde(Kunstmuseum museum) {
        super(museum);
        // TODO Auto-generated constructor stub
    }

Das ist ja nur der Name des Parameters. Der Parameter ist vom Typ Kunstmuseum und heißt museum. Den Namen kannst du frei wählen, z.B.

Java:
public Gemaelde(Kunstmuseum kleinesWeissesKaninchen) {
        super(kleinesWeissesKaninchen);
        // TODO Auto-generated constructor stub
    }

Das ändert nichts an der Funktion.

Ansonsten stehe ich leider gerade echt auf dem Schlauch was ich mit dem besagten kunstmuseum, welches bei der Initialisierung im Test mitgegeben wird, tun kann.

Du fügst einfach dem museum ein Kunstwerk hinzu mit addKunstwerk(). Steht doch schon oben wie das geht. Das Kunstwerk fügt sich selbst dem museum hinzu.
 

Snaer

Aktives Mitglied
Du fügst einfach dem museum ein Kunstwerk hinzu mit addKunstwerk(). Steht doch schon oben wie das geht. Das Kunstwerk fügt sich selbst dem museum hinzu.

Ist das aber nicht das was ich in meiner Methode addWerk bereits versuche?

Code:
public void addWerk (Kunstwerk werk) {
    this.werke.add(werk);
}
Beziehungsweise muss ich für den Aufruf kunstmuseum.addKunstwerk(this); dann eine neue Liste kunstmuseum in der Klasse Kunstwerk erstellen?
 

temi

Top Contributor
Ist das aber nicht das was ich in meiner Methode addWerk bereits versuche?

Nein. Das ist eine Methode der Klasse Kunstmuseum, mit der man einem Kunstmuseum ein Kunstwerk hinzufügen kann. Damit das geschieht musst du sie natürlich auch irgendwo mal aufrufen.

Beziehungsweise muss ich für den Aufruf kunstmuseum.addKunstwerk(this); dann eine neue Liste kunstmuseum in der Klasse Kunstwerk erstellen?

Das schon gleich gar nicht. Es ist ja alles schon da, was du brauchst.
 

temi

Top Contributor
Java:
class Foo {
 
    Bar bar; // Foo hat ein Bar als Instanzvariable
 
    public void setBar(Bar bar){ // und eine Methode mit der bar gesetzt werden kann
        this.bar = bar;
    }
}

class Bar {
 
    public Bar(Foo foo) { // Bar erwartet ein Foo als Parameter
        foo.setBar(this); // und setzt sich selbst als das bar von foo
    }
}

public static void main(String[] args) {

    Foo foo = new Foo();
    Bar bar = new Bar(foo);
    // jetzt gibt es sowohl eine Instanz von Foo, als auch von Bar und Foo.bar ist gleich bar. Logisch oder?
}

Und jetzt ist deine Übertragungsleistung gefordert! ;)
 

Snaer

Aktives Mitglied
Aber bezieht sich kunstmuseum.addKunstwerk(this); nicht automatisch auf eine Liste oder habe ich da etwas falsch verstanden?
Java:
class Foo {
 
    Bar bar; // Foo hat ein Bar als Instanzvariable
 
    public void setBar(Bar bar){ // und eine Methode mit der bar gesetzt werden kann
        this.bar = bar;
    }
}

class Bar {
 
    public Bar(Foo foo) { // Bar erwartet ein Foo als Parameter
        foo.setBar(this); // und setzt sich selbst als das bar von foo
    }
}

public static void main(String[] args) {

    Foo foo = new Foo();
    Bar bar = new Bar(foo);
}

Und jetzt ist deine Übertragungsleistung gefordert! ;)
Da die Klasse Kunstwerk ein museum als Variable besitzt gehe ich davon aus, dass ich einen ähnlichen Konstruktor in der Klasse Kunstmuseum erstellen muss.
Code:
public class Kunstmuseum {

    public Kunstmuseum (Kunstwerk kunstwerk) {
        kunstwerk.setMuseum(this);
    }
}
Ist die Main Methode in deinem Beispiel dabei essentiell notwendig? Oder würde diese quasi vom Test bereits ausgeführt werden, da dort ja 2 Objekte erzeugt werden?
 

temi

Top Contributor
Aber bezieht sich kunstmuseum.addKunstwerk(this); nicht automatisch auf eine Liste oder habe ich da etwas falsch verstanden?

Erläutere mal was du damit genau meinst?

Worauf sich die Methode addKunstwerk() bezieht, dass hast du ja mit deinem Code selbst in der Hand.

Da die Klasse Kunstwerk ein museum als Variable besitzt gehe ich davon aus, dass ich einen ähnlichen Konstruktor in der Klasse Kunstmuseum erstellen muss.
Nein.

Irgendwie scheinst du nur herumzuprobieren ohne es zu verstehen. Hast du genau verstanden, was der Beispielcode macht?
 

Snaer

Aktives Mitglied
Erläutere mal was du damit genau meinst?

Worauf sich die Methode addKunstwerk() bezieht, dass hast du ja mit deinem Code selbst in der Hand.
Ist addKunstwerk nicht automatisch auf eine Liste bezogen? Also quasi eine Vorgehensweise um ein Objekt zu einer bestimmten Liste hinzuzufügen, im Fall von kunstmuseum.addKunstwerk() dann, um ein Kunstwerk Objekt zu einer kunstmuseum Liste hinzuzufügen? Oder wird das Kunstwerk durch den Befehl dann einfach nur der Klasse zugeordnet?
Nein.

Irgendwie scheinst du nur herumzuprobieren ohne es zu verstehen. Hast du genau verstanden, was der Beispielcode macht?
So wie ich es verstanden habe müsste es sich so verhalten:
Also du hast ja 2 verschiedene Klassen einmal Foo und Bar. Ich bin jetzt davon ausgegangen, dass die Klasse Foo quasi äquivalent zu meiner Klasse Kunstwerk sei, da du in Foo eine Variable bar vom Typ Bar erstellst. Ähnliches tue ich ja in meiner Klasse Kunstwerk indem ich ein musuem vom Typ Kunstmuseum erzeuge.
Und anschließend übergibst du in der Klasse Bar dann ein foo vom Typ Foo und fügst es durch den Befehl foo.setBar(this); dann zu einer passenden Bar hinzu.
 

temi

Top Contributor
Ist addKunstwerk nicht automatisch auf eine Liste bezogen? Also quasi eine Vorgehensweise um ein Objekt zu einer bestimmten Liste hinzuzufügen, im Fall von kunstmuseum.addKunstwerk() dann, um ein Kunstwerk Objekt zu einer kunstmuseum Liste hinzuzufügen?

Ja. In der Regel sind Methoden die mit add...() beginnen, dazu da um einer Liste etwas hinzuzufügen. Da du diese Methode selbst programmiert hast, weißt du ja genau, was sie tut.

Du möchtest doch ein Kunstwerk einer Liste von Kunstwerken in einem Museum hinzufügen. Dann mach das doch endlich!

So wie ich es verstanden habe müsste es sich so verhalten:

Ersetze Foo mit Kunstmuseum und Bar mit Kunstwerk.

Und anschließend übergibst du in der Klasse Bar dann ein foo vom Typ Foo und fügst es durch den Befehl foo.setBar(this); dann zu einer passenden Bar hinzu.

Das stimmt so nicht. Es wird dem Konstruktor von Bar eine Instanz von Foo übergeben und dieser Instanz von Foo wird eine Instanz von Bar hinzugefügt.
 
K

kneitzel

Gast
Eine Methode fügt nur ein Sache hinzu, die man mit einem Objekt machen kann.

Das ist also so, als ob ich weiß, wie man Auto fährt (Ich habe eine Methode fahre(Fahrzeugm Ziel). Ich kann Auto fahren und will von A nach B. Und es steht ein Auto bei mir gerade so rum..... Wie komme ich jetzt von A nach B?
Da nutze ich mein Wissen um das Auto fahren und nehme das Auto und fahre nach B. Also fahre(auto, B).

Also einem Kunstmuseum kann man Kunstwerke hinzu fügen. Aber das nützt doch nichts, so lange niemand das tut!
Also muss jemand das addKunstwerk aufrufen! Daher schau doch einmal, was für Code durchlaufen wird!
Wenn dir da noch der Überblick fehlt: Schreib in jede Methode ein println Befehl! Also sowas:
Code:
public class SomeClass {
  public void someMethod() {
    System.out.println("In SomeClass::someMethod!");
    // ....
  }
}

Wenn Du dann ein Kunstwerk erstellst, dann siehst Du ja auf der Konsole, was für Funktionen durchlaufen werden ....
Und da kannst Du dann mal schauen:

Was brauchst Du, um ein Kunstwerk einem Museum hinzuzufügen?
a) Ein Museum
b) Ein Kunstwerk
==> Hast du beides, dann kannst Du addKunstwerk aufrufen auf dem Mesum und das Kunstwerk übergeben....
 

Snaer

Aktives Mitglied
Also einem Kunstmuseum kann man Kunstwerke hinzu fügen. Aber das nützt doch nichts, so lange niemand das tut!
Also muss jemand das addKunstwerk aufrufen! Daher schau doch einmal, was für Code durchlaufen wird!


Was brauchst Du, um ein Kunstwerk einem Museum hinzuzufügen?
a) Ein Museum
b) Ein Kunstwerk
==> Hast du beides, dann kannst Du addKunstwerk aufrufen auf dem Mesum und das Kunstwerk übergeben....

Also ich brauche ein Kunstwerk und ein Musuem.. ein Museum habe ich ja selbst noch mal initialisiert. Muss ich das selbe dann auch für ein Kunstwerk machen, also in der Klasse Kunstmuseum dann eine Variable Kunstwerk kunstwerk; initialisieren oder ist die Klasse Klasse Kunstwerk dabei genügend?

Du möchtest doch ein Kunstwerk einer Liste von Kunstwerken in einem Museum hinzufügen. Dann mach das doch endlich!

Ersetze Foo mit Kunstmuseum und Bar mit Kunstwerk.

Das stimmt so nicht. Es wird dem Konstruktor von Bar eine Instanz von Foo übergeben und dieser Instanz von Foo wird eine Instanz von Bar hinzugefügt.
Also liege ich dann richtig in der Annahme das mir noch eine Variable Kunstwerk kunstwerk in der Klasse Kunstmuseum fehlt? Da die Klasse Foo ja eine bar initialisiert.

Ich verstehe leider noch nicht wieso die Methode addWerk nicht das besagte Kunstwerk zu dem Museum hinzufügt.
Also ich rufe sie scheinbar nirgendwo auf soweit habe ich es verstanden, aber wie rufe ich denn die Methode auf?
Mittels kunstmuseum.addwerk(this);?
 
K

kneitzel

Gast
Du brauchst keine Variable mehr im Kunstmuseum. Kunstmuseum hat eine Funktion um ein Kunstwerk hinzu zufügen.

Das ist also so, wie bei Dir: Dir kann man Geld geben. Aber wenn Dir niemand Geld gibt, dann hast Du kein Geld. Da spielen auch weitere Geldbörsen oder Tresore oder sonst was keine Rolle....

Alles was fehlt ist doch, dass Dir nun endlich jemand Geld gibt!

Und im Konstruktor von Kunstwerk hast Du doch
a) ein Kunstwerk (this)
b) Das Kunstmuseum (Parameter des Konstruktors)

Also wie bekommst Du im Konstruktor nun das Kunstwerk in das Museum?
 

temi

Top Contributor

temi

Top Contributor
Also ich brauche ein Kunstwerk und ein Musuem.. ein Museum habe ich ja selbst noch mal initialisiert. Muss ich das selbe dann auch für ein Kunstwerk machen, also in der Klasse Kunstmuseum dann eine Variable Kunstwerk kunstwerk; initialisieren oder ist die Klasse Klasse Kunstwerk dabei genügend?

Schau doch mal den Test an:
Java:
    public void test() {
        Kunstmuseum kunstmuseum = new Kunstmuseum(); // hier wird das Museum erzeugt!!!
        kunstmuseum.setName("Koblenzer Kunstmuseum");
        // asserts...
       
        Kunstwerk kunstwerk1 = new Statue(kunstmuseum); // und hier die Kunstwerke!!!
        Kunstwerk kunstwerk2 = new Gemaelde(kunstmuseum);
        // asserts...

Da hier nirgends eine Methode aufgerufen wird, die ein Kunstwerk dem Museum hinzufügt, muss das zwangsläufig irgendwo im Konstruktor der Kunstwerke passieren.

Die beiden Kunstwerke bekommen ja auch das Museum als Parameter mit.
 

Snaer

Aktives Mitglied
Du brauchst keine Variable mehr im Kunstmuseum. Kunstmuseum hat eine Funktion um ein Kunstwerk hinzu zufügen.

Das ist also so, wie bei Dir: Dir kann man Geld geben. Aber wenn Dir niemand Geld gibt, dann hast Du kein Geld. Da spielen auch weitere Geldbörsen oder Tresore oder sonst was keine Rolle....

Alles was fehlt ist doch, dass Dir nun endlich jemand Geld gibt!

Und im Konstruktor von Kunstwerk hast Du doch
a) ein Kunstwerk (this)
b) Das Kunstmuseum (Parameter des Konstruktors)

Also wie bekommst Du im Konstruktor nun das Kunstwerk in das Museum?
Meinst du diesen Konstruktor ?
Code:
 public Kunstwerk(Kunstmuseum museum) {
        if (museum == null) {
            throw new IllegalArgumentException();
        }
        this.setMuseum(museum);
    }
Ich nehme dass an ich das Kunstwerk dann durch den Befehl museum.addKunstwerk(this); im Konstruktor hinzufügen kann.
 

temi

Top Contributor
Sprich so dann? ^^
Code:
 public Kunstwerk(Kunstmuseum museum) {
        if (museum == null) {
            throw new IllegalArgumentException();
        }
        this.setMuseum(museum);
        museum.addKunstwerk(this);
    }

Also was ich überhaupt nicht verstehe und auch kein Verständnis dafür habe:

Warum probierst du es nicht einfach mal aus?

Wenn du Java lernst, dann musst du doch zwangsläufig auch einen Computer haben, auf dem Java (und bestenfalls auch eine IDE) installiert ist.

Schreib deine Klassen und teste sie!

Notfalls schreib eine kleine main() mit:
Java:
Kunstmuseum kunstmuseum = new Kunstmuseum(); // hier wird das Museum erzeugt!!!

Kunstwerk kunstwerk1 = new Statue(kunstmuseum); // und hier die Kunstwerke!!!
Kunstwerk kunstwerk2 = new Gemaelde(kunstmuseum);

System.out.println(kunstmuseum.getWerke().size()); // Erwartet: 2 => Stimmt das Ergebnis?
 

Snaer

Aktives Mitglied
Also was ich überhaupt nicht verstehe und auch kein Verständnis dafür habe:

Warum probierst du es nicht einfach mal aus?

Wenn du Java lernst, dann musst du doch zwangsläufig auch einen Computer haben, auf dem Java (und bestenfalls auch eine IDE) installiert ist.

Schreib deine Klassen und teste sie!

Da ich zuvor blind ausprobiert hatte und in die falsche Richtung gedacht hatte war ich mir unsicher ob ich in die richtige Richtung denke :rolleyes:

Jedenfalls habe ich den Fehler zwar weg bekommen, jedoch habe ich nun das Problem, dass meine add Methode in einer Endlosschleife endet und ich mir auch nach längerem ausprobieren leider nicht bewusst werde woran es liegt..

Code:
public abstract class Kunstwerk {

    private String name;
    private double preis;
    private Kunstmuseum museum;
    private Person besitzer;

    public Kunstwerk(Kunstmuseum museum) {
        if (museum == null) {
            throw new IllegalArgumentException();

        }

        this.setKunstmuseum(museum);
        museum.addKunstwerk(this);
    }

    public void setKunstmuseum(Kunstmuseum museum) {
        this.museum = museum;
    }

    public Kunstmuseum getMuseum() {
        return museum;
    }

    public void setBesitzer(Person besitzer) {
        this.besitzer = besitzer;
    }

    public Person getBesitzer() {
        return besitzer;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPreis() {
        return preis;
    }

    public void setPreis(double preis) {
        this.preis = preis;
    }

}




import java.util.ArrayList;

public class Kunstmuseum {

    private ArrayList<Kunstwerk> werke = new ArrayList<Kunstwerk>();
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setWerke(ArrayList<Kunstwerk> werke) {
        this.werke = werke;
    }

    public ArrayList<Kunstwerk> getWerke() {

        return werke;
    }

    public void addKunstwerk(Kunstwerk kunstwerk) {

        addKunstwerk(kunstwerk);
        this.werke.add(kunstwerk);
    }

    public void removeKunstwerk(Kunstwerk kunstwerk) {

        removeKunstwerk(kunstwerk);
        this.werke.remove(kunstwerk);
    }
}

Soweit ich es bis jetzt verstanden habe, habe ich mir selbst mit der Methode public void addKunstwerk(Kunstwerk kunstwerk) in der Klasse Kunstmuseum eine Endlosschleife gebaut.
 

Snaer

Aktives Mitglied
Richtig. Eine endlose Rekursion, die irgendwann mit einem StackOverflowError abbrechen wird.
Würdest du mir erläutern woran es liegt? Denn der Grund ist mir nicht ersichtlich.
Ich kann ja erläutern, wie ich es mir vorgestellt hatte.
Ich bin davon ausgegangen das ich in Kunstwerk durch museum.addKunstwerk(this); die Methode in der Klasse Kunstmuseum aufrufe und es dann anschließend durch die Methode in Kunstmuseum hinzufüge.
Das ich da irgendetwas falsch verstanden habe bzw. übersehe ist mir durch den Fehler bewusst, nur leider finde ich nicht heraus was genau.
 

Snaer

Aktives Mitglied
Das ist doch der einfachste StackOverflow dens gibt du rufst ja direkt in addKunstwerk nochmal addKunstwerk auf...
Okay dummer Fehler :rolleyes: Ich hatte es bereits weggelassen, nur wenn ich es weg lasse bekomme ich eine andere Fehlermeldung zurück.
Code:
java.lang.AssertionError: expected:<Person@65e579dc> but was:<null>
    at org.junit.Assert.fail(Assert.java:88)
    at org.junit.Assert.failNotEquals(Assert.java:834)
    at org.junit.Assert.assertEquals(Assert.java:118)
    at org.junit.Assert.assertEquals(Assert.java:144)
    at PublicTests.test(PublicTests.java:41)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:52)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:27)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
    at org.junit.runner.JUnitCore.runMain(JUnitCore.java:77)
    at org.junit.runner.JUnitCore.main(JUnitCore.java:36)
Da diese zuvor nicht da war hatte ich es wieder rein geschrieben.
 

mihe7

Top Contributor

Snaer

Aktives Mitglied
Das ist ein Fehler, der anzeigt, dass ein Test fehlschlägt:


Der Test erwartet eine Person, es wird aber null geliefert. Dem Test nach soll beim Erzeugen eines Kunstwerks automatisch eine Person als Besitzer des Kunstwerks angelegt werden.

Okay da ich in der Klasse Person einen leeren Konstruktor habe nehme ich mal an, dass dort mit einem bestimmten Aufruf einen Besitzer setzen kann, liege ich da richtig?
Oder muss ich den Fehler in der Klasse Kunstwerk suchen, da ich dort ja auch die Variable Besitzer erstellt habe?
 

mihe7

Top Contributor
Dem Test nach soll beim Erzeugen eines Kunstwerks automatisch eine Person als Besitzer des Kunstwerks angelegt werden.
Das war eine falsche Annahme. Bei Euch wird ja alles mögliche über die Konstruktoren erledigt.

Okay da ich in der Klasse Person einen leeren Konstruktor habe nehme ich mal an, dass dort mit einem bestimmten Aufruf einen Besitzer setzen kann, liege ich da richtig?
Deine Klasse Person muss über einen Konstruktor verfügen, der als Parameter ein Kunstwerk erhält. In dem Konstruktor kannst Du dann die setBesitzer-Methode des übergebenen Kunstwerks verwenden.
 

Snaer

Aktives Mitglied
Okay also es tut mir wirklich sehr leid, dass ich vermutlich dezent anstrengend bin :rolleyes:
Code:
public Person(Kunstwerk kunstwerk) {
    kunstwerk.setBesitzer(this);
    }
Der Fehler ist damit behoben, jedoch entsteht noch eine NullPointerException
Code:
Person person1 = new Person(kunstwerk1);
        assertEquals(person1, kunstwerk1.getBesitzer());
        person1.setName("Person1");
        assertEquals("Person1",person1.getName());
        assertEquals(1,person1.getKunstwerke().size());
        assertTrue(person1.getKunstwerke().contains(kunstwerk1));
    }

}

java.lang.NullPointerException
    at PublicTests.test(PublicTests.java:44)

Liege ich richtig wenn ich sage, dass der Test prüft ob person1.getKunstwerke().size()); 1 ergibt und da dies allerdings bei mir 0 ergibt er mir stattdessen den Fehler ausspuckt?
 

mihe7

Top Contributor
Liege ich richtig wenn ich sage, dass der Test prüft ob person1.getKunstwerke().size()); 1 ergibt und da dies allerdings bei mir 0 ergibt er mir stattdessen den Fehler ausspuckt?
Wenn Zeile 44 die Zeile
Code:
assertTrue(person1.getKunstwerke().contains(kunstwerk1));
ist, dann bedeutet die NullPointerException (NPE), dass person1.getKunstwerke() null liefert.
 
K

kneitzel

Gast
Der Fehler ist damit behoben, jedoch entsteht noch eine NullPointerException
Code:
Person person1 = new Person(kunstwerk1);
        assertEquals(person1, kunstwerk1.getBesitzer());
        person1.setName("Person1");
        assertEquals("Person1",person1.getName());
        assertEquals(1,person1.getKunstwerke().size());
        assertTrue(person1.getKunstwerke().contains(kunstwerk1));
    }

}

java.lang.NullPointerException
    at PublicTests.test(PublicTests.java:44)

Liege ich richtig wenn ich sage, dass der Test prüft ob person1.getKunstwerke().size()); 1 ergibt und da dies allerdings bei mir 0 ergibt er mir stattdessen den Fehler ausspuckt?

Also eine NullPointerException ist doch deutlich von einem "expected: 1 but was 0" zu unterscheiden.
Wenn Du eine NPE bekommst, dann liegt es nicht daran, dass etwas 0 war wo er 1 erwartet hätte.

Da wir nicht sehen können, was Zeile 44 ist, können wir nur bedingt etwas aussagen. Deine Aussage scheint auf die Zeile
assertEquals(1,person1.getKunstwerke().size());
hin zu deuten. Also vermutlich liefert getKunstwerke() einfach nur null, weil die entsprechende Instanzvariable hinter dem Getter nicht initialisiert wurde. Also erst einmal im Konstruktor auch diese Instanzvariable initialisieren.
Danach wird es aber wohl zu einem "expected 1 but was 0" kommen, denn Du wirst im Konstruktor von Person nicht die Person als Besitzer hinterlegen.
 

Luca H

Mitglied
Danach wird es aber wohl zu einem "expected 1 but was 0" kommen, denn Du wirst im Konstruktor von Person nicht die Person als Besitzer hinterlegen.
Weswegen wird die Person nicht als Besitzer hinterlegt, wird das nicht durch den Methodenaufruf erledigt?
Code:
public Person(Kunstwerk kunstwerk) {
    kunstwerk.setBesitzer(this);
    }
 

mihe7

Top Contributor
Weswegen wird die Person nicht als Besitzer hinterlegt, wird das nicht durch den Methodenaufruf erledigt?
Die Beziehung ist bidirektional, die auf zwei Einzelbeziehungen abgebildet wird: ein Kunstwerk kann eine Person (als Besitzer) haben und eine Person kann beliebig viele Kunstwerke besitzen.

Die "Kunstwerk-hat-Besitzer"-Beziehung wird in Deinem Konstruktor gesetzt, nicht aber die Beziehung "Besitzer-besitzt-Kunstwerke".
 

Luca H

Mitglied
Die "Kunstwerk-hat-Besitzer"-Beziehung wird in Deinem Konstruktor gesetzt, nicht aber die Beziehung "Besitzer-besitzt-Kunstwerke".
[/QUOTE]

Also muss ich im Prinzip einen neuen Konstruktor, in der Klasse Peron initialisieren, der die "Besitzer-besitzt-Kunstwerk" Beziehung beschreibt oder stehe ich grade auf dem Schlauch? :D
 

Snaer

Aktives Mitglied
Muss es nicht eher dann einen Methoden Aufruf sein, bei der Kunstwerke Liste, die auf die setBesitzer Methode in der Klasse Kunstwerk verweist? Sprich ähnlich wie bei den Besitzer Verweis
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
W UML Diagramm implementieren Java Basics - Anfänger-Themen 2
X MainClass im UML Diagramm Java Basics - Anfänger-Themen 2
lilrack UML Diagramm für Parkplatzverwaltung Java Basics - Anfänger-Themen 8
B UML Klassen Diagramm zu Java Code Programmieren und ausführen Java Basics - Anfänger-Themen 21
M Erste Schritte von UML Diagramm zum Code Java Basics - Anfänger-Themen 29
C UML Diagramm in Java implementieren-Korrektur Java Basics - Anfänger-Themen 8
J OOP Probleme mit UML-Diagramm Java Basics - Anfänger-Themen 6
T X-Y-Diagramm Analyse Java Basics - Anfänger-Themen 2
E OOP UML Diagramm Java Basics - Anfänger-Themen 4
V SVG Diagramm erstellen Java Basics - Anfänger-Themen 2
B Erste Schritte Brauche Hilfe für ein UML Diagramm Java Basics - Anfänger-Themen 7
D Werte aus Excel in Diagramm einfügen Java Basics - Anfänger-Themen 6
D Array in Diagramm ausgeben Java Basics - Anfänger-Themen 7
M Uml Diagramm->Java Java Basics - Anfänger-Themen 1
F Aus UML Diagramm Quelltext Java Basics - Anfänger-Themen 7
F uml diagramm! Java Basics - Anfänger-Themen 4
S UML Diagramm in Eclipse Java Basics - Anfänger-Themen 1
M CSV in Diagramm Java Basics - Anfänger-Themen 3
S UML-Diagramm und Java Java Basics - Anfänger-Themen 5
D Diagramm in der Konsole erstellen Java Basics - Anfänger-Themen 13

Ähnliche Java Themen

Neue Themen


Oben