Vererbung Schlechter Stil?

MarKe

Mitglied
Hallöchen zusammen in die Runde! :)
Ich bin neu hier und habe dieses Forum per Zufalls-Google'lei gefunden und dachte mir, dass ich mich mal anmelde.
Zu mir: Ich habe vor drei Wochen angefangen, Java zu lernen und versuche mich quasi selbst per "Crash-Kurs" weiterzubilden. Mein Ziel ist es, bei einer ausgesuchten Firma eine Ausbildung zum Fachinformatiker - Anwendungsentwicklung zu beginnen und ich hoffe, dass ich mit diesem Tutorial mein Ziel erreiche und die Firma überzeuge kann.

Folgendes:

Ich bearbeite zur Zeit Übungsaufgaben des Java Tutorial interaktiv - Programmieren lernen mit Java und bin mittlerweile bei Kapitel 50 angekommen. Nun denn, ich habe mich an die Programmieraufgaben gewagt, die da besagen:

"Aufgabe 1 — Old Scotch

Erstellen Sie eine Klasse Artikel mit den Instanzvariablen artikelNr, bezeichnung, einkaufspreis und lagerzeit (Monate). Deklarieren Sie zwei Konstanten:

final double HANDELSSPANNE = 0.6 ; // 60 Prozent des Einkaufspreises
final double MWST = 0.19 ; // 19 Prozent

Erstellen Sie einen Konstruktor, der die Artikelobjekte initialisiert (alle Instanzvariablen).

Schreiben Sie eine öffentliche anzeigen() Methode, die die Artikelinformationen ausgibt und eine öffentliche Methode zum Berechnen des Verkaufspreises:

public int berechneVerkaufspreis()

Der Verkaufspreis ergibt sich aus der Summe von Einkaufspreis und Handelsspanne zuzüglich Mehrwertsteuer. Das Ergebnis wird auf eine ganze Zahl abgerundet.

Erzeugen Sie in der Klasse ArtikelTester zwei Artikelobjekte und testen Sie die Methoden.

Die Ausgabe des Programms sieht dann z.B. folgendermaßen aus:

Code:
SC123-F "DUFFY MALT Whisky" EK: 10.0 VK: 19 Euro Lagerzeit: 3 Monate
SC347-A "GLEN MORANGIE MALT Whisky" EK: 55.0 VK: 104 Euro Lagerzeit: 15 Monate"[/SIZE]





Die zweite Aufgabe lautet:

"Aufgabe 2 — Sonderposten

Leiten Sie eine Klasse Sonderposten von der Klasse Artikel ab. Die Subklasse erweitert die Superklasse, um die Instanzvariable rabatt.

Erstellen Sie unter Verwendung des Konstruktors der Superklasse einen Konstruktor, der die Objekte der Subklasse initialisiert. Die Initialisierung der Instanzvariablen rabatt wird vom Konstruktor je nach Lagerzeit übernommen. Bei einer Lagerzeit größer 12 Monate wird ein Rabatt auf dem Verkaufspreis von 30 Prozent gewährt. Andernfalls beträgt der Rabatt 10 Prozent.

Schreiben Sie eine Methode anzeigen() für die Subklasse, die die anzeigen() Methode der Superklasse überschreibt.

Schreiben Sie eine Methode berechneVerkaufspreis(), die ebenfalls die Methode der Superklasse überschreibt.

Die Ausgabe des Programms sieht dann z.B. ungefähr wie folgt aus:

Code:
SC123-F "DUFFY MALT Whisky" EK: 10.0 VK: 19 Euro Lagerzeit: 3 Monate

Sonderposten:
SC123-F "DUFFY MALT Whisky" EK: 10.0 VK: 17 Euro Lagerzeit: 3 Monate
(VK <alt>: 19 Euro; Rabatt: 10%)

Sonderposten:
SC347-A "GLEN MORANGIE MALT Whiskey" EK: 55.0 VK: 72 Euro Lagerzeit: 15 Monate
(VK <alt>: 104 Euro; Rabatt: 30%)"[/SIZE]





Meine Frage: An sich habe ich die Aufgaben verstanden und auch bearbeitet. Es hieß nur z.B. speziell in Aufgabe 1, dass ich 4 Instanzvariablen deklarieren soll. Bei mir sind es 7 :oops: .
Aufgabe 2 war auch relativ logisch, doch habe ich im Nachhinein mein Programm mal durchgeschaut und auf dem ersten Blick denke ich mir: "Hm, irgendwie unübersichtlich und wahrscheinlich ein ganz schlechter Stil, sodass andere vielleicht Probleme bekommen könnten, es nachzuvollziehen."

Kann ich mein Programm durch einfache Kniffe irgendwie... nun... vereinfachen?

Ich zeige Euch mal mein Programm:

Java:
class Artikel    //Superclass
{		
	double verkaufspreis;
	String artikelNr;
	String bezeichnung;
	double einkaufspreis;
	int lagerzeit;
	final double HANDELSSPANNE = 0.6;
	final double MWST = 0.19;
	
  public Artikel(String art, String bez, double preis, int zeit)
	{
		artikelNr = art;
		bezeichnung = bez;
		einkaufspreis = preis;
		lagerzeit = zeit;
	}
  public void anzeigen()
	{
		System.out.println(artikelNr + " " + bezeichnung + " EK: " + einkaufspreis + " VK: " + (int)verkaufspreis + " Lagerzeit: " + lagerzeit + " Monate");
	}
  public int berechneVerkaufspreis()
	{ 
		verkaufspreis = (einkaufspreis + (einkaufspreis * HANDELSSPANNE));
		verkaufspreis = verkaufspreis + verkaufspreis * MWST;
		return (int)verkaufspreis;
	}
}


class Sonderposten extends Artikel    //Subclass
{
	int rabatt;
	double rabattpreis;
	
  public Sonderposten(String art, String bez, double preis, int zeit)
    {
	  super(art, bez, preis, zeit);
	    if ( lagerzeit > 12 )
	    {
		  rabatt = 30;
	    }
	    if (lagerzeit <= 12)
	    {
		  rabatt = 10;
	    }
    }
  public void anzeigen()
  	{
	  System.out.println("\n++SONDERPOSTEN++");
	  System.out.println(artikelNr + " " + bezeichnung + " EK: " + einkaufspreis + " VK: " + (int)rabattpreis + " Lagerzeit: " + lagerzeit + " Monate");
	  System.out.println("(VK <alt>: " + (int)verkaufspreis + " Rabatt: " + rabatt + "%)");
	  
  	}

  public int berechneVerkaufspreis()
  	{
	  rabattpreis = super.berechneVerkaufspreis() - super.berechneVerkaufspreis() / 100.0 * rabatt;
	  return (int)rabattpreis;
  	}	
}


public class ArtikelTester    //Testclass
{
  public static void main( String[] args )
  {
	  Artikel artikelA = new Artikel("SC123-F", "DUFFY MALT Whisky", 10.0, 3);
	  Artikel artikelB = new Artikel("SC347-A", "GLEN MORANGIE MALT Whiksy", 55.0, 19);
	  artikelA.berechneVerkaufspreis();
	  artikelB.berechneVerkaufspreis();
	  artikelA.anzeigen();
	  artikelB.anzeigen();
	  
	  Sonderposten sonderA = new Sonderposten("SC123-F", "DUFFY MALT Whisky", 10.0, 3);
	  Sonderposten sonderB = new Sonderposten("SC347-A", "GLEN MORANGIE MALT Whiksy", 55.0, 19);
	  sonderA.berechneVerkaufspreis();
	  sonderB.berechneVerkaufspreis();
	  sonderA.anzeigen();
	  sonderB.anzeigen();
  }
}


Zur Erklärung:
Ich bin ein ganz blutiger (fast schon verblutender :D) Anfänger und hoffe, dass ich Euch mit meinem Problemchen nicht langweile.

Vielen Dank schonmal im Voraus!

Liebe Grüße
Marcel
 
Zuletzt bearbeitet:

kaoZ

Top Contributor
Erstmal zu Aufgabe 1:

Das hier sind Konstanten, da
Code:
final
, kann der zugewiesene Wert nicht mehr geändert werden , meistens sind diese auch noch
Code:
static
damit auch ohne vorhandene Instanz darauf zugegriffen werden kann. ( Zu erkennen sind diese an der Trennung durch
Code:
_
und an der durchgehend verwendeten UPPERCASE Schreibweise.

Java:
final double HANDELSSPANNE = 0.6;
final double MWST = 0.19;

und deine Instanzvariablen ( Attribute / (4 Stück an der Zahl )) :

Java:
String artikelNr, bezeichnung;
double einkaufspreis;
int Lagerzeit;

Das
Code:
Verkaufspreis
auch als Instanzvariable zugänglich sein soll, wird nicht erwähnt/gefordert!

Zudem sollten Attribute einer Klasse als
Code:
[B]private[/B]
deklariert werden , damit diese nach außen hin nicht zugänglich sind.

Desweiteren mal zum allgemeinen Stil

Java:
 public Artikel(String art, String bez, double preis, int zeit)
    {
        artikelNr = art;
        bezeichnung = bez;
        einkaufspreis = preis;
        lagerzeit = zeit;
    }

könnte man der übersicht halber auch so umsetzen

Java:
public Artikel(String artikelNr, String bezeichnung, double einkaufspreis, int lagerZeit){
  this.artikelNr = artikelNr;
  this.bezeichnung = bezeichnung;
  this.einkaufspreis = einkaufspreis;
  this.lagerzeit = lagerzeit;
}

Hier kannst du nun gut anhand des
Code:
this.
Zeigers erkennen das hier eine Attribut der Klasse ( also eine Instanzvariable bezeichnet wird, so ist es auch möglich den Parametern den gleichen Namen zuzuweisen, und man sieht im Konstruktor sofort was genau übergeben werden muss/soll.

insofern dies nicht vorausgesetzt ist , solltest du ebenfalls die main Methode, wen du schon eine Testklasse erstellen sollst , in jene Separate Klasse packen , hier sieht es so aus als wenn alles als innere Klassen realisiert worden wäre, was ebenfalls zu Unübersichtlichkeit führen wird.

[EDIT]Man könnte nun noch weiter gehen und z.B Artikel in ein Enum auslagern, aber das ist denke ich hier nicht gefordert :)[/EDIT]
 
Zuletzt bearbeitet:

Gucky

Top Contributor
kaoZ hat viele Dinge schon richtig gesagt. Ich würde noch hinzufügen, dass solche Programmweiten Konstanten meistens als static definiert werden um Speicherplatz zu sparen. Oder zumindest in C++ wird das so gemacht und in Java kann es zumindest nicht schaden.

Der Übersicht halber setze ich immer ein
Code:
this.
vor alle Attribute einer Klasse. Es ändert nichts am Kompilat aber ich finde, dass ist übersichtlicher.

In berechneRabattPreis() gehst du den Umweg über eine Variable. Das kann man so machen, man kann den Wert aber auch direkt zurückgeben. Ich halte das direkte Zurückgeben für besser aber das musst du wissen.

Zu dem, von kaoZ schon angesprochenen, unnötigen Attribut: Versuch möglichst Klassenvariablen zu vermeiden. Dann hast du oben nicht so einen Wust aus Vatiablendeklarationen und die unbenutzten Variablen nehmen nicht unnötig Speicherplatz weg.

Im Konstruktor von Sonderposten machst du eine if Abfrage, die guckt, ob der Wert größer als 12 ist und eine, die guckt, ob der Wert unter oder gleich 12 ist. Das wird mit einem else Block gemacht, da es nur zwei Möglichkeiten gibt. Und ein Tipp: wenn if Abfragen sich gegenseitig ausschließen oder sie nicht alle bearbeitet werden sollen (spart Rechenleistung) wird das mit einem else if Block gemacht.

Das hört sich jetzt viel an. Es sind aber alles nur Kleinigkeiten. Ich bin durch deinen Code durchgestiegen und fand ihn nicht kompliziert.
 

MarKe

Mitglied
Ich bedanke mich erstmal vielmals für Eure Tipps.

@Kaoz, ja ich werde das Programm dahingehend nochmal später ändern. Wenn ich aber alle Instanzvariablen als private markiere, wie gebe ich denn dann den "alten Preis" in Aufgabe 2 aus?
Lokale Variablen halten sich doch nur bis Methoden-Ende, oder?
Oder soll ich dort in der anzeigen()-Methode auch einen super."methode()"-Aufruf starten, um den Verkaufspreis zu bekommen? Das ist immer diese eine Kleinigkeit, die ich noch nicht ganz so auf die Reihe kriege. Wenn ich z.B. die Instanz-Variable verkaufspreis weglasse und dafür etliche Methoden aufrufe, erhöht sich doch gleichzeitig auch die Rechneranforderung. Wie kann ich den verkaufspreis also in der subclass deklarieren, ohne dass ich auf die Instanzvariable der superclass zurückgreifen muss?
Viele Fragezeichen, sorry :(

@Gucky, dir auch vielen Dank für deine Tipps, werde sie nachher mal umsetzen. :)
Ja, das mit der if-Anweisung ist mir auch kurz darauf aufgefallen. Habe es nur noch nicht ausgebessert. War ja totaler Quatsch, eine zweite if-Anweisung zu schreiben, wenn ich sowieso nur zwei Werte brauche. Und da ich ja möchte, dass der eine "Weg" nicht unnötig berechnet wird und nochmal durchgekaut wird (if "so und so", dann nochmal "dann if so und so"), werde ich das zweite if streichen und einfach durch ein schnödes else ersetzen. Vielen Dank dafür. :)
 

Gucky

Top Contributor
Instanzvariablen werden private gekennzeichnet und durch getter und setter kann man auf sie zugreifen. Sie sind trotzdem genau so deklariert, wie jetzt nur halt als private.
 

kaoZ

Top Contributor
Mit settern sollte man wiederum sparsam sein, und lieber die Initialisierung in Konstruktor handhaben, sonst kann es passieren das z.b Inkonsistente Objekte erzeugt werden.
Bitte dafür am besten die wertzuweisung über den
Konstruktor an und einen öffentlichen getter.

Außer natürlich Du möchtest Werte nach Initialisierung später ändern, dann arbeitest du natürlich mit settern :)
 
Zuletzt bearbeitet:

Unlikus

Mitglied
in php und anderen Sprachen ist es übllich statt privat eher protected zu setzen. Und ich finde das auch sehr angebracht, da man in seinen Kindsklassen auch auf diese Variablen zugreifen will und eventuell andere getter, setter braucht, als die Vaterklasse. Nur was wirklich absolut privat ist würde ich auch als private definieren.
 

kaoZ

Top Contributor
Mit protected gestattest Du allen Klassen im selben package Zugang, dies ist in den meisten Fällen unerwünscht, Außerdem kann ich mich nicht daran erinnern jemals ein als protected deklariertes Attribut ( in Java ) gesehen zu haben.
 

kaoZ

Top Contributor
Vorrausgesetzt es ist notwendig das Subklassen auf die Attribute auch uneingeschränkten Zugang erhalten, kann man protected als sichtbarkeit verwenden, man könnte aber auch einfach auf die öffentlichen getter zugreifen, insofern in der Superklasse definiert .
 
Zuletzt bearbeitet:

Unlikus

Mitglied
in settern wird ja auch normalerweise eine Validirung mit implementiert. Wenn man in der Kindklasse nun eine andere Validierung braucht wird die Umsetzung wieder unschön, weil man an der Superklasse den setter entsprechend anpassen muss.
Dass ein protected ein Attribut im gesamten package Sichtbar macht, erklärt den natürlich den spählichen Einsatz in Java (In php hat man das Problem zum Beispiel nicht).
Vielleicht wären für Java ja 2 verschiedene Arten von protected angebracht, eine packageweit eine nur für Kindsklassen.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
S Unbeschaeftigten Thread in einer Schleife schlafen legen? Schlechter Stil? Java Basics - Anfänger-Themen 7
S Schlechter Stil beim Exception Handling Java Basics - Anfänger-Themen 6
H schlechter objektorientierter stil Java Basics - Anfänger-Themen 6
berserkerdq2 Lange Variablennamen schlechter Programmierstyle? Java Basics - Anfänger-Themen 4
U Methoden Code Quality und Stil Java Basics - Anfänger-Themen 5
kaoZ Stil ? - ....Nein nicht das Ende des Besens ^^ Java Basics - Anfänger-Themen 11
B Grundsätzliche Klassen-Struktur/Stil Java Basics - Anfänger-Themen 12
S Mein Code is unübersichtlich - besseren Stil Java Basics - Anfänger-Themen 6
J Getter und Setter auch intern benutzen - guter Stil? Java Basics - Anfänger-Themen 31
nabla Code Stil -- Eclipse Warnings Java Basics - Anfänger-Themen 9
H [Stil] Exceptions in der Klasse behandeln oder throwen? Java Basics - Anfänger-Themen 62
P DotComVersenken -Spiel im Schiffeversenken-Stil - erstellen- Komm jetzt nicht weiter. Java Basics - Anfänger-Themen 11
P Spiel im Schiffe-Versenken Stil, Problem mit Erstellung des zweidimensionalen ARRAYs Java Basics - Anfänger-Themen 7
S sauberer Stil von return Wert (try, catch, finally) Java Basics - Anfänger-Themen 9
hdi Programmier-Stil : Speicher vs. Quellcode Java Basics - Anfänger-Themen 67
U Vernünftige Strukturierung, Guter Stil,. Java Basics - Anfänger-Themen 12
K BufferedReader im Konstruktor // guter Stil ? Java Basics - Anfänger-Themen 2
F Zugriff auf Instanzvariablen, Frage zum guten Stil Java Basics - Anfänger-Themen 2
J Guter Stil der Java-Programmierung Java Basics - Anfänger-Themen 5
G Array mit Schleife durchlaufen - guter Stil? Java Basics - Anfänger-Themen 20
frau-u guter Stil - wie macht mans am Besten? Java Basics - Anfänger-Themen 8

Ähnliche Java Themen

Neue Themen


Oben