Abstrakte Klasse, Konstruktorkette, Attribute setzen

Bitte aktiviere JavaScript!
Hallo liebe Forengemeinde :D

Derzeit bin ich dabei mir Java beizubringen und bin bei einer Aufgabe auf ein Problem gestoßen bei dem ich ein paar grundlegende Fragen habe.

Es gibt zwei Klassen, eine grundlegende Klasse (Product) ist abstrakt, die andere (Pen) ist eine "normale" Klasse. Darüberhinaus gibt es noch ein Enum, welches die aktuelle Währung (Currency) für das jeweilige Produkt festlegt:

Abstrakte Klasse Product:
Java:
public abstract class Product {
    
    //attributes
    private double price;
    private String name;
    private Currency currency;
    
    //constructor
    Product(double price, String name, Currency currency) {
        this.price = price;
        this.name = name;
        this.currency = currency;
    }
    
    //get-set-methods
    public void setPrice(double price) {
        this.price = price;
    }
    
    //methods
    public abstract void buyProduct();

}
Klasse Pen:
Java:
public class Pen extends Product{
    
    //constructor
    Pen(double price, String name, Currency currency) {
        super (price, name, currency);
        setPrice(1.22);
        
    }
    
    //methods
    public void buyProduct() {
    }

}
Enum Currency:
Java:
public enum Currency {

        EURO, DOLLAR, YEN;
}
Meine Problem: Ich möchte die Attribute für die Produkte möglichst in der abstrakten Klasse Product lassen und mit der Klasse Pen und dem entsprechendem Konstruktor diese Attribute übergeben. Dabei bin ich auf das Problem gestoßen, dass ich diese wegen mangelnder Sichtbarkeit in der Klasse Pen nicht deklarieren und per super() an die abstrakte Klasse Product übergeben kann.

Mit einer set-Methode kann ich das machen, wobei ich mir irgendwie nicht vorstellen kann, dass das besonders sinnvoll ist.
Soll ich diese Attribute direkt in der Kindklasse deklarieren?

Ich frage mich einfach welche Vorgehensweise hier sozusagen üblich und sinnvoll ist.

Ich hoffe mein Problem kommt halbwegs verständlich rüber...
 
A

Anzeige




Vielleicht hilft dir unser Kurs hier weiter —> (hier klicken)
und per super() an die abstrakte Klasse Product übergeben kann.
Warum?
Java:
    public Pen(double price, String name, Currency currency) {
        super (1.22, name, currency);      
    }
PS: Warum machst du deine Konstruktoren nicht public? Hat das einen besonderen Grund?
PPS: Wenn du die Attribute aus der Oberklasse in der Unterklassen verwenden möchtest, könntest du sie protected setzen.
 
Danke für die schnelle Antwort.

Warum? - Meine Idee ist eine grundlegende Klasse für Produkte zu erstellen und bei den Kindklassen (also den eigentlichen Produkten) nur Besonderheiten extra zu deklarieren. Die Attribute will ich aber trotzdem in der Kindklasse mit Werten belegen.

Konstruktoren nicht public - Nein hat keinen bestimmten Grund. Mir fällt spontan auch nicht ein was dagegen sprechen würde.
Protected - Auch ne gute Idee :D. Hatte ich beides jetzt nicht auf dem Schirm.
 
Java:
    Pen(double price, String name, Currency currency) {
        super (1.22, "Pen", currency.EURO);
    }
Das hier funktioniert...hatte ich bisher nicht ausprobiert.
 
Java:
    Pen(double price, String name, Currency currency) {
        super (1.22, "Pen", currency.EURO);
    }
Das hier funktioniert...hatte ich bisher nicht ausprobiert.
Wenn du das so machst sind die Werte ja fest. Dann musst du sie natürlich auch nicht im Konstruktor übergeben
Java:
Pen() {
    super(1.22, "Pen", currency.EURO);
}
 
Ich frage mich einfach welche Vorgehensweise hier sozusagen üblich und sinnvoll ist.
Ich glaube nicht, dass man eine generelle Vorgehensweise angeben kann, da es immer davon abhängt, was man erreichten möchte.

Da du in deinem Fall in deinen Unterklassen feste Werte übergeben möchtest, ist das mit dem Konstruktor (Vorschlag #5 von @Robat) sinnvoll.

Weitere Setter sind da nicht notwendig, da sich ja an den Attributen nichts mehr ändert. Insofern wäre es auch nicht so dumm entsprechende Getter-Methoden in der Basisklasse zu definieren und diese dann entweder public oder protected zu machen. Darüber kann die Kindklasse auch auf die Werte lesend zugreifen.
 
Ich habs jetzt doch anders gemacht. Die Attribute hab ich protected gesetzt und deklariere sie dann einfach direkt im Konstruktor der Kindklasse. Sieht alles unkomplizierter und übersichtlicher aus :D.

Danke Robat für die schnelle Hilfe :)

Edit: Mir super() wollte er currency.EURO nicht nehmen, deswegen habe ich das jetzt so gemacht.

Java:
public abstract class Product {
   
    //attributes
    protected double price;
    protected String name;
    protected Currency currency;
   
    //constructor
    Product() {
    }
   
    //methods
    public abstract void buyProduct();

}
Java:
public class Pen extends Product {
   
    //constructor
    Pen() {
        this.price = 1.22;
        this.name = "Pen";
        this.currency = currency.EURO;
    }
   
    //methods
    public void buyProduct() {
    }

}
 
Sehr schön ist das aber nicht. Stell dir vor du wölltest bei dem Preis noch eine Abfrage auf Gültigkeit machen. So müsstest du die in jeder Kindsklasse einfügen. Das geht schon über den Konstruktor - auch mit dem Enum.
Java:
public abstract class Product {

    //attributes
    protected double price;
    protected String name;
    protected Currency currency;

    //constructor
    protected Product(double price, String name, Currency currency) {
        this.price = price;
        this.name = name;
        this.currency = currency;
    }
    ...
}

public class Pen extends Product {
    public Pen() {
        super(1.22, "PEN", Currency.EURO);
    }
    ....
}
 
Weitere Setter sind da nicht notwendig, da sich ja an den Attributen nichts mehr ändert. Insofern wäre es auch nicht so dumm entsprechende Getter-Methoden in der Basisklasse zu definieren und diese dann entweder public oder protected zu machen. Darüber kann die Kindklasse auch auf die Werte lesend zugreifen.
Die Idee gefällt mir. Werde ich so machen. Danke dir.
 
Ihr habt Recht. Currency.Euro. Jetzt klappt es auch mit super().

Eine Frage noch: Soll ich die Attribute dann private lassen oder ist protected da sinnvoller? In der Kindklasse greife ich jetzt ja nicht mehr direkt drauf zu.
 
Wenn du in der Kindsklasse nicht drauf zugreifst kannst du sie ruhig private machen. Faustregel was die Sichtbarkeit angeht:
"So wenig wie möglich, so viel wie nötig". Da du von außen keinen direkten Zugriff brauchst, kannst du sie private machen.
 
Oki. Es funktioniert jetzt alles. Danke Robat und temi für die schnelle Hilfe. Ich mach dann mal weiter :D.

Man sieht sich.
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben