Sub- und Superklassen

jono

Top Contributor
Ich habe jetzt zu #75, welches ich gerade kopiert habe,
Java:
    private Produkt produkt = new Produkt(); Meldung: Cannot instantiate the type Produkt
    private Zutat zutat1 = new Zutat(); Meldung: The constructor Zutat() is undefined
das Problem.
Java:
    public void doSomething() {
        int value = foo.getValue();
    }
}
Das ist schon fertig.
 

jono

Top Contributor
Java:
/root/autocorrectormRPQPudir/PublicTests.java:9: error: constructor Kaese in class Kaese cannot be applied to given types;
        Milchprodukt k = new Kaese();
                         ^
  required: String,int,double,Zutat[]
  found: no arguments
  reason: actual and formal argument lists differ in length
/root/autocorrectormRPQPudir/PublicTests.java:13: error: constructor Zutat in class Zutat cannot be applied to given types;
        Zutat z1 = new Zutat();
                   ^
  required: String,int
  found: no arguments
  reason: actual and formal argument lists differ in length
/root/autocorrectormRPQPudir/PublicTests.java:26: error: constructor Zutat in class Zutat cannot be applied to given types;
        Zutat z2 = new Zutat();
                   ^
  required: String,int
  found: no arguments
  reason: actual and formal argument lists differ in length
/root/autocorrectormRPQPudir/PublicTests.java:30: error: constructor Zutat in class Zutat cannot be applied to given types;
        Zutat z3 = new Zutat();
                   ^
  required: String,int
  found: no arguments
  reason: actual and formal argument lists differ in length
/root/autocorrectormRPQPudir/PublicTests.java:35: error: cannot find symbol
        assertFalse(contains(k.getZutaten(),z1));
                              ^
  symbol:   method getZutaten()
  location: variable k of type Milchprodukt
/root/autocorrectormRPQPudir/PublicTests.java:36: error: cannot find symbol
        assertFalse(contains(k.getZutaten(),z2));
                              ^
  symbol:   method getZutaten()
  location: variable k of type Milchprodukt
/root/autocorrectormRPQPudir/PublicTests.java:37: error: cannot find symbol
        assertFalse(contains(k.getZutaten(),z3));
                              ^
  symbol:   method getZutaten()
  location: variable k of type Milchprodukt
/root/autocorrectormRPQPudir/PublicTests.java:41: error: cannot find symbol
        assertTrue(contains(k.getZutaten(),z1));
                             ^
  symbol:   method getZutaten()
  location: variable k of type Milchprodukt
/root/autocorrectormRPQPudir/PublicTests.java:42: error: cannot find symbol
        assertTrue(contains(k.getZutaten(),z2));
                             ^
  symbol:   method getZutaten()
  location: variable k of type Milchprodukt
/root/autocorrectormRPQPudir/PublicTests.java:43: error: cannot find symbol
        assertTrue(contains(k.getZutaten(),z3));
                             ^
  symbol:   method getZutaten()
  location: variable k of type Milchprodukt
/root/autocorrectormRPQPudir/PublicTests.java:45: error: cannot find symbol
        assertFalse(contains(k.getZutaten(),z3));
                              ^
  symbol:   method getZutaten()
  location: variable k of type Milchprodukt
/root/autocorrectormRPQPudir/Milchprodukt.java:6: error: Produkt is abstract; cannot be instantiated
    private Produkt produkt = new Produkt();
                              ^
/root/autocorrectormRPQPudir/Milchprodukt.java:7: error: constructor Zutat in class Zutat cannot be applied to given types;
    private Zutat zutat1 = new Zutat();
                           ^
  required: String,int
  found: no arguments
  reason: actual and formal argument lists differ in length

Woran liegt es, habe es wirklich gewissenhaft bearbeitet, bitte um einen netten Hinweis :).
 
K

kneitzel

Gast
Du versuchst Instanzen der Klassen zu erzeugen, aber Du hast nur Konstruktoren mit Parametern. Und das sagt er dir dann. Die Meldung sieht dann z.B. so aus:
Code:
/root/autocorrectormRPQPudir/PublicTests.java:9: error: constructor Kaese in class Kaese cannot be applied to given types;
        Milchprodukt k = new Kaese();
                         ^
  required: String,int,double,Zutat[]
  found: no arguments
  reason: actual and formal argument lists differ in length
Übersetzt: Fehler: Der Konstruktor Kaese in der Klasse Kaaese kann nicht mit den angegebenen Typen verwendet werden.
Dann zeigt er die Codestelle mit dem new Kaese();
Dann sagt er Dir: Er erwartet 4 Parameter: Ein String, ein int, ein double und dann ein Array von Zutat
Du hast: Keine Argumente angegeben.
Ursache: Aktuelle und formale Argumentenliste unterscheiden sich in der Länge.

Oder in anderen Worten: Schau Dir immer die Konstruktoren an. (Hinweis: Wenn es keinen Konstruktor im Code gibt, dann erstellt Java einen Standard Konstruktor ohne Parameter). Die Paramter, die da gefordert werden, musst du dann auch immer mit angeben.
 

jono

Top Contributor
Java:
private Produkt produkt = new Produkt();
    private Zutat zutat1 = new Zutat();
Was soll ich das jetzt machen ??
 

Rahza

Mitglied
Ich glaube in der Aufgabenstellung steht garnichts speziell über Konstruktoren. Dann nimm einfach nur Default Konstruktoren (ohne Parameter).
 

jono

Top Contributor
Java:
public abstract class Milchprodukt extends Produkt implements Produzierbar {
   
    private double fettgehalt;
    private Zutat[] zutaten = null;
    private Produkt produkt = new Produkt();
    private Zutat zutat1 = new Zutat();

   

    public Zutat getZutat1() {
        return zutat1;
    }

    public void setZutat1(Zutat zutat1) {
        this.zutat1 = zutat1;
    }

    public double getFettgehalt() {
        return fettgehalt;
    }

    public void setFettgehalt(double fettgehalt) {
        this.fettgehalt = fettgehalt;
    }

    Milchprodukt(String name, int anzahlVorhanden, double fettgehalt, Zutat[] zutaten, Produkt produkt, Zutat zutat1) {
        super(name, anzahlVorhanden);
        this.zutaten = zutaten;
        this.fettgehalt = fettgehalt;
        this.produkt = produkt;
        this.zutat1 = zutat1;
        this.zutaten = new Zutat[10];

    }
   
    public boolean produzieren(int anzahl) {
       
        if (anzahl <= zutaten.length) {
            int anzahlVorhanden = produkt.getAnzahlVorhanden();
            int anzahlVerfuegbarerEinheiten = zutat1.getAnzahlVerfuegbarerEinheiten();
            anzahlVorhanden +=anzahl;
            anzahlVerfuegbarerEinheiten -=anzahl;
            return true;
        }

        return false;
    }

    public boolean addZutat(Zutat zutat) {
        for (int i = 0; i < zutaten.length; i++) {
            if (zutaten[i] == null) {
                zutaten[i] = zutat;
                return true;
            }
        }
        return false;

    }

    public boolean removeZutat(Zutat zutat) {
        for (int i = 0; i < zutaten.length; i++) {
            if (zutaten[i] == zutat) {
                zutaten[i] = null;
                return true;
            }
        }
        return false;
    }

}
 

jono

Top Contributor
Was will der blöde Test von mir ... Ich habe alle Konstruktoren, mit dem was required ist , versehen , bevor diese Fehlermeldung auftrat. Obwohl diese Parameter enthalten sind tritt die Meldung auf
 

jono

Top Contributor
Bitte um Hilfe. Das ist wirklich etwas, was sich als Anfänger auch mit Grundlagenwissen evtl. bearbeiten lässt, aber ich finde es nicht unbedingt sehr einleuchtend, vor allem weil die Fehlermeldung auftritt trotz korrekt übergebener Parameter.
 
K

kneitzel

Gast
Ich glaube in der Aufgabenstellung steht garnichts speziell über Konstruktoren. Dann nimm einfach nur Default Konstruktoren (ohne Parameter).
Also nur um das noch einmal zu erläutern:

Default Konstruktoren erzeugt Java, wenn es keinen Konstruktor im Source Code gibt. Sobald man einen Konstruktor geschrieben hat in einer Klasse, dann gibt es in der Klasse keinen Default Konstruktor mehr.

Aber man kann jeder Klasse natürlich noch einen Default Konstruktor manuell hinzufügen. Wenn Du also die Klasse Kaese hast, dann kannst Du noch einen Konstruktor in der Klasse einfügen, der wie folgt aussieht:
Java:
public Kaese() {}

Beachte: Ein Konstruktor hat einen Rückgabewert! Da darf also kein "void" oder so stehen. Sobald Du public void Kaese() schreibst, ist es kein Konstruktor mehr sondern eine einfache Methode!

Somit bedeutet der Ratschlag von Rahza, dass Du bei allen Klassen noch sicherstellst, dass so ein Konstruktor vorhanden ist bzw. dass Du andere Konstruktoren einfach löschst (Evtl. ist letzteres aber ungünstig, da die evtl. irgendwo verwendet werden! Daher würde ich weitere Konstruktoren hinzufügen!)
 

jono

Top Contributor
Implicit super constructor Produkt() is undefined. Must explicitly invoke another constructor
-> tritt auf wenn ich in Milchproduktklasse Milchprodukt() {] als Defaultkonstruktor einfüge.
 

Rahza

Mitglied
Im Grunde hast du doch bei Milchprodukt nur das Attribut fettgehalt und dann noch wegen der Aggregation das Array zutaten. Das new produkt und new zutat braucht man doch garnicht oder? Vor allem solltest du in der Aufgabestellung schauen, wie die genaue Bezeichnung der Aggregationsbeziehung ist. Darauf legt der Prof ja immer Wert dass alles genauso übernommen wird wie in der Aufgabenstellung. Was die Komstruktoren angeht: Dort wo man Komstruktoren brauchte wurde in den vergangenen Wochen ja konkret angegeben mit welchern Parametern wir die erstellen sollen. Da das diesmal nicht der Fall ist gehe ich mal von aus, dass der Default Konstruktor reicht
 

jono

Top Contributor
Java:
public abstract class Milchprodukt extends Produkt implements Produzierbar {
    
    private double fettgehalt;
    private Zutat[] zutaten = null;
    private Produkt produkt = new Produkt();
    private Zutat zutat1 = new Zutat();

    public Zutat getZutat1() {
        return zutat1;
    }

    public void setZutat1(Zutat zutat1) {
        this.zutat1 = zutat1;
    }

    public double getFettgehalt() {
        return fettgehalt;
    }

    public void setFettgehalt(double fettgehalt) {
        this.fettgehalt = fettgehalt;
    }

    public Milchprodukt() {
    
        this.zutaten = new Zutat[10];

    }
    
    public boolean produzieren(int anzahl) {
        
        if (anzahl <= zutaten.length) {
            int anzahlVorhanden = produkt.getAnzahlVorhanden();
            int anzahlVerfuegbarerEinheiten = zutat1.getAnzahlVerfuegbarerEinheiten();
            anzahlVorhanden +=anzahl;
            anzahlVerfuegbarerEinheiten -=anzahl;
            return true;
        }

        return false;
    }

    public boolean addZutat(Zutat zutat) {
        for (int i = 0; i < zutaten.length; i++) {
            if (zutaten[i] == null) {
                zutaten[i] = zutat;
                return true;
            }
        }
        return false;

    }

    public boolean removeZutat(Zutat zutat) {
        for (int i = 0; i < zutaten.length; i++) {
            if (zutaten[i] == zutat) {
                zutaten[i] = null;
                return true;
            }
        }
        return false;
    }

}

?
 

jono

Top Contributor
Java:
    public Milchprodukt(String name, int anzahlVorhanden) {
        super(name, anzahlVorhanden);
        this.zutaten = new Zutat[10];

    }
das brauche ich doch, da Produkt mit den dortigen Parametern die Elternklasse darstellt?
 

albanhu

Mitglied
public Milchprodukt(String name, int anzahlVorhanden, double fettgehalt,Zutat[] zutaten) {
super(name, anzahlVorhanden);
this.fettgehalt = fettgehalt;
this.zutaten = new Zutat [10];
}

so sieht meins aus habe noch die werte die wir in Milchprodukt brauchen reingepackt …. #selbstNichtsicher ...
 
K

kneitzel

Gast
Du übergibst ein Array mit Zutaten ... das solltest du dann für Zutaten verwenden und kein neues Array erzeugen ...
Sorry, bin jetzt weg vom Computer und schreibe auf dem Handy, daher nicht mehr ausführlich .... morgen erläutere ich noch einmal was bezüglich dem letzten Problem ... Nur kurz so viel: wenn du komplett so default Konstruktoren haben willst, dann darfst du den nicht in der Super Klasse vergessen!
 

temi

Top Contributor
Leute, arbeitet mal an eurem Textverständnis und lest die Aufgabe noch mal durch!

Ihr braucht keine leeren Standardkonstruktoren! Nirgends!

Produkt hat als Attribute: name und anzahlVorhanden.

Milchprodukt erbt von Produkt und hat als Attribut: fettgehalt. Hier ist als Besonderheit noch die Aggregation von zehn Zutaten. Die werden allerdings nicht über den Konstruktor zugewiesen, sondern über die darunter beschriebene Methode addZutat(). In der Aufgabe steht hierzu nur "zu Beginn sollen alle Elemente null sein". Außerdem implementiert es die Schnittstelle Produzierbar.

Kaese erbt von Milchprodukt und hat keine weiteren Attribute.

Yoghurt erbt von Milchprodukt und hat als Attribut: fruchtYoghurt

Zutat hat als Attribute: name und anzahlVerfuegbareEinheiten, sowie eine zusätzliche Methode nachkaufen().

Es wird nicht explizit erwähnt, aber man kann davon ausgehen, dass nur die angegebenen Attribute über den Konstruktor gesetzt werden.

Wie geht das also:

1. Klassenrumpf hinschreiben
2. extends oder implements entsprechend ergänzen
3. Attribute mit den entsprechenden Typen hinschreiben.
4. Konstruktor von der IDE erzeugen lassen. IntelliJ kann das komplett mit dem Aufruf von super() und allen geerbten Attributen. Notfalls halt händisch.
5. Getter/Setter von der IDE erzeugen lassen.

Jetzt sind ca. 20 Minuten vorbei und es stehen alle Klassen bis auf zwei komplett da.

6. Die fehlenden Methoden von Milchprodukt und Zutat implementieren. Fertig!
 
Zuletzt bearbeitet:

temi

Top Contributor
public Milchprodukt(String name, int anzahlVorhanden, double fettgehalt,Zutat[] zutaten) {
super(name, anzahlVorhanden);
this.fettgehalt = fettgehalt;
this.zutaten = new Zutat [10];
}

so sieht meins aus habe noch die werte die wir in Milchprodukt brauchen reingepackt …. #selbstNichtsicher ...

Bis auf die zutaten im Konstruktor in den Parametern richtig. Und, schau mal genau hin, du verwendest den Parameter auch nicht im Code.
 

mihe7

Top Contributor
Ich verstehe nicht wieso ihr so antwortet, man kann das doch normal klären, ohne sich so zu äußern(auch wenn es schwer fällt für euch als Profis). Wir beschäftigen uns nun mal erst seit kurzem damit. @temi Was ist denn daran alles scheiße ?

@jono, @Xknight Hier geht es nicht um Profis oder darum, dass Ihr Euch erst seit "kurzem" damit beschäftigt. Keiner erwartet, dass Ihr schlagartig Java könnt, aber absolute Grundlagen werden vorausgesetzt - vor allem nach Wochen.

Die Reaktionen hier brauchen Euch nicht wirklich zu wundern. Man gewinnt den Eindruck, dass Ihr nicht einmal gewillt seid, wenigstens die Aufgabenstellung richtig zu lesen. Man kann in Hunderten Beiträgen was erklären, das scheint auf der einen Seite rein und auf der anderen raus zu gehen. Hauptsache, Ihr habt am Ende was, das Ihr abgeben könnt. Die Woche drauf fängt das Drama von vorne an.

Ich kann Euch nur dringend raten, an Eurer Einstellung zu arbeiten. Schule ist vorbei. Es gibt keinen Lehrer mehr, der Euch alles hinterher trägt, Euch Aufgaben gibt, damit Ihr beschäftigt seid oder Euch abfragt, weil er seine Noten machen und sich gegenüber Schulleitung und Eltern verantworten muss, wenn das arme Kind schlechte Noten hat.

Die Aufgaben sind in erster Linie dazu gedacht, dass Ihr das Erlernte vertiefen und überprüfen könnt (das setzt voraus, dass man etwas erlernt hat), ein Gefühl dafür bekommt, wo es hakt - und es hakt bei Euch an allen Ecken und Enden.

Wenn Euch das Verständnis in den Vorlesungen oder Skripten nicht vermittelt werden konnte, dann nehmt Euren Bibliotheksausweis, besorgt Euch entsprechende Bücher und arbeitet(!) damit, d. h. lesen, und praktisch(!) anwenden. Programmieren lernt man nur (und nur) by doing.

Dem entsprechend würde man erwarten, dass ihr vielleicht auch mal unabhängig von den Aufgaben Fragen habt, entweder zu Code, den Ihr selbst probiert oder allgemein zum Verständnis. Diesbezüglich kann ich mich an nichts erinnern.

Nicht falsch verstehen: das ist nicht böse gemeint. Es ist einfach ein Tritt in den Allerwertesten, damit Ihr endlich aufwacht und "in die Pötte" kommt.
 

Rahza

Mitglied
Ich habe das mit dem Standardkonstruktor geschrieben, da in den vergangenen Aufgaben bei den Konstruktoren konkret angegeben war, welche Paramater übergeben werden sollen. Auf Nachfrage wurde nur eine schwammige Antwort vom Übungsleiter gegeben, dass man einfach mal die Default Konstruktoren reinpacken sollte.
 

temi

Top Contributor
Ich habe das mit dem Standardkonstruktor geschrieben, da in den vergangenen Aufgaben bei den Konstruktoren konkret angegeben war, welche Paramater übergeben werden sollen. Auf Nachfrage wurde nur eine schwammige Antwort vom Übungsleiter gegeben, dass man einfach mal die Default Konstruktoren reinpacken sollte.
In der Regel ist das allerdings keine gute Idee, denn der leere Standardkonstruktor erzeugt sozusagen ein "hohles" Objekt und ein Objekt sollte nach der Erzeugung seine Funktion voll erfüllen können. Dazu gehört auch, dass es konsistent initialisiert ist.

Es gibt natürlich Fälle, wo viele Parameter vorliegen, die evtl. auch nicht alle benötigt werden. Da bieten sich dann Lösungen, wie z.B. das Builder Pattern an. Das führt hier allerdings zu weit.
 
Zuletzt bearbeitet:

mihe7

Top Contributor
Allerdings würde ich bei solch Aufgaben empfehlen, sich peinlichst genau an die Vorgabe zu halten - ich habe z. B. im Klassendiagramm (Kommentar #40) auch extra den Tippfehler beim Obst übernommen :)
 

temi

Top Contributor
Allerdings würde ich bei solch Aufgaben empfehlen, sich peinlichst genau an die Vorgabe zu halten - ich habe z. B. im Klassendiagramm (Kommentar #40) auch extra den Tippfehler beim Obst übernommen :)
Meinst du das jetzt Pro oder Contra Standardkonstruktor?

Im Text der Aufgabe wird er nicht erwähnt. Für die geforderte Klassenstruktur wird er nicht benötigt. Ich würde ihn erst mal weglassen und erst wenn die (uns nicht bekannten) Tests fehlschlagen notfalls noch ergänzen.
 

Rahza

Mitglied
In der Regel ist das allerdings keine gute Idee, denn der leere Standardkonstruktor erzeugt sozusagen ein "hohles" Objekt und ein Objekt sollte nach der Erzeugung seine Funktion voll erfüllen können. Dazu gehört auch, dass es konsistent initialisiert ist.

Es gibt natürlich Fälle, wo viele Parameter vorliegen, die evtl. auch nicht alle benötigt werden. Da bieten sich dann Lösungen, wie z.B. das Builder Pattern an. Das führt hier allerdings zu weit.
Ja mir ging es auch eher darum was genau die Profs gesagt haben. Aus Programmierersicht hast du natürlich Recht bzw. kannst das besser einschätzen als ich. Hier wurde ja auch in irgendeinem Thread auch schon die vorletzte Aufgabe diskutiert wo auch explizit Komstruktoren genannt wurden. Bei dem Übungsleiter weiß man aver nie so wirklich. Kann auch sein, dass meine Abgabe jetzt falsch war, da ich nur die Default Konstruktoren genommen hab
 

temi

Top Contributor
Kann auch sein, dass meine Abgabe jetzt falsch war, da ich nur die Default Konstruktoren genommen hab
Nein, vermutlich liegst du richtig. Ich hab mir mal die Ausschnitte aus den fehlgeschlagenen Tests einige Seiten weiter vorne angeschaut und offenbar werden alle Objekte mit Standardkonstruktor + Setteraufrufe erzeugt. Eigentlich nicht sehr gut gelöst und vermutlich den Tests geschuldet (hoffe ich mal).

Insofern gilt dieses, weil es technisch die saubere Lösung ist:
Im Text der Aufgabe wird er nicht erwähnt. Für die geforderte Klassenstruktur wird er nicht benötigt. Ich würde ihn erst mal weglassen
aber in Verbindung mit diesem:
und erst wenn die (uns nicht bekannten) Tests fehlschlagen notfalls noch ergänzen

Weil wir gerade bei technisch sauberen Lösungen sind, noch eine Ergänzung für dich @Rahza, weil du offenbar Interesse an der Sache hast: Auch die automatisch erzeugten Getter/Setter für alle Attribute sind nicht ganz zum objektorientierten Gedanken konform. Eine Klasse sollte soviele Implementationsdetails verbergen wir möglich und nur nach außen geben was unbedingt notwendig ist.
 
Zuletzt bearbeitet:

Rahza

Mitglied
@Rahza kann es sein, dass Ihr noch keine super-Aufrufe hattet?
Grundsätzlich wurde das schon in der Vorlesung erklärt, weil es ja eben zum Vererbungs-Thema gehört. Ich meine auch die super-Aufrufe schon in den Präsenzaufgaben gesehen zu haben, aber das wurde wirklich nur angerissen. Übrigens unsere neue Aufgabe ist schon raus. Ich versuche das mal am Wochenende zu lösen. Sieht nicht wirklich schwierig aus. Notfalls weiß ich ja wo ich Hilfe bekomme?

Ich habe das Forum auch im Grunde erst letzte Woche gefunden bzw. mich angemeldet. Hätte ich das noch eine Woche vorher gefunden, hätte ich die Compiler-Fehler beheben können, denn für die gibt es 0 Punkte. Am Ende hat es sehr wahrscheinlich daran gelegen, dass ich auf Teufel komm raus eine public-static Methode machen wollte, aber die Methode nur public sein sollte.
 

Anhänge

  • PMP_Ass08.pdf
    62 KB · Aufrufe: 3

Rahza

Mitglied
Nein, vermutlich liegst du richtig. Ich hab mir mal die Ausschnitte aus den fehlgeschlagenen Tests einige Seiten weiter vorne angeschaut und offenbar werden alle Objekte mit Standardkonstruktor + Setteraufrufe erzeugt. Eigentlich nicht sehr gut gelöst und vermutlich den Tests geschuldet (hoffe ich mal).

Insofern gilt dieses, weil es technisch die saubere Lösung ist:

aber in Verbindung mit diesem:


Weil wir gerade bei technisch sauberen Lösungen sind, noch eine Ergänzung für dich @Rahza, weil du offenbar Interesse an der Sache hast: Auch die automatisch erzeugten Getter/Setter für alle Attribute sind nicht ganz zum objektorientierten Gedanken konform. Eine Klasse sollte soviele Implementationsdetails verbergen wir möglich und nur nach außen geben was unbedingt notwendig ist.
Was genau meinst du mit Implementationsdetails? Also dass man durch die Getter und Setter Zugriff auf gewisse Attribute bekommt und man versuchen sollte nicht überall Zugriff zu gewähren?
 

Ähnliche Java Themen

Neue Themen


Oben