molchi: Vererbung

Hallo Leute,
ich bin gerade dabei etwas über Java zu lernen und habe folgende
(für Euch wahrscheinlich triviale) Aufgabe gestellt bekommen:
Gegeben ist die Klasse Punkt.java

001 /**
002  *Punkt.java
003  *Klasse, von der andere Klassen erben
004  */
005
006 public class Punkt {
007   protected double x,y;
008
009   public Punkt(double x, double y){
010     this.x = x;
011     this.y = y;
012   }
013
014 /**
015   * @return x,y Koordinaten eines Punktes werden zurueckgegeben.
016   */
017    public String text(){
018      return new String("("+x+", "+y+")");
019    }
020
021 /** Gibt die Koordinaten des Punktes (x,y) aus.
022   * Ruft dazu die Methode text().
023   * @return Formatierte Ausgabe der Punktkoordinaten.
024   * @see Punkt#text()
025   */
026   public String toString(){
027     return new String("Punkt: "+text());
028   }
029
030 }

Nun soll ich noch 3 weitere Klassen Quadrat.java, Rechteck.java und Kreis.java, die von der Klasse Punkt direkt oder indirekt abgeleitet werden programmieren.

Bedingungen sind

Quadrat.java: Subklasse von Punkt.
verwendet double-Werte x und y aus der Klasse Punkt und speichert zusätzlich einen double-Wert deltaX, der die Hälfte einer Seitenlänge des Quadrates darstellt·
Initialisierung erfolgt im Konstruktor der Klasse Quadrat und im Konstruktor der Superklasse·
die Klasse enthält eine getUmfang-Methode, die den Umfang des Quadrates bestimmen sol

Rechteck.java: Subklasse von Quadrat.·
verwendet double-Werte x und y aus der Klasse Punkt, deltaX aus der Klasse Quadrat und speichert zusätzlich einen double-Wert deltaY, der die Hälfte der anderen Seitenlänge darstellt.
Initialisierung erfolgt im Konstruktor der Klasse Rechteck und im Konstruktor der Superklassen
die Klasse enthält eine getFlaeche-Methode, welche die Fläche des Rechteckes berechnen soll

Kreis.java: Unterklasse von Punkt
verwendet double-Werte x und y aus der Klasse Punkt und speichert zusätzlich einen double-Wert radius
radius - Radius des Kreises
Initialisierung erfolgt im Konstruktor der Klasse Kreis und im Konstruktor der Superklasse
die Klasse enthält außerdem noch die beiden Methoden: getFlaeche und getUmfang, die Fläche und Umfang des Kreises berechnen sollen.

Ich finde die Aufgabe für einen Anfänger schon recht schwierig und bräuchte da einen Rat. Ich wollte so in etwa anfangen:
 /**
  *Kreis.java
  *Klasse, die von Punkt erben tut
  */

public class Kreis extends Punkt {
   protected double radius;

public Kreis(double x, double y, double radius){
  super(x, y);
     this.radius = radius;
     //text();
     //toString();
   }
 Oder ist das schon völliger blödsinn?

Gruß molchi

  1. guten Abend,

    Ich finde die Aufgabe für einen Anfänger schon recht schwierig und bräuchte da einen Rat. Ich wollte so in etwa anfangen:
     public class Kreis extends Punkt {
       protected double radius;

    bis dahin sollte das in Ordnung gehen, obwohl ich nicht ganz einsehen kann, warum du hier "protected" gesetzt hast

    public Kreis(double x, double y, double radius)

    Das ist aber problematisch. Du hast bereits deine Klassendefinition vorgenommen, und jetzt willst du noch eine Methode "Kreis" reinbasteln? Nenne die Methode anders, dann könnte es getrost so weitergehen:

    {
      super(x, y);

    this.radius = radius;

    Das ist nicht ganz einleuchtend, könnte aber funktionieren.

    //text();
         //toString();
       }

    Oder ist das schon völliger blödsinn?

    Nein. Aber viel zu wenig, um sehen zu können, was draus werden soll

    Grüße aus Berlin

    Christoph S.

    1. Hallo,

      Ich finde die Aufgabe für einen Anfänger schon recht schwierig und bräuchte da einen Rat. Ich wollte so in etwa anfangen:
      public class Kreis extends Punkt {
         protected double radius;
      bis dahin sollte das in Ordnung gehen, obwohl ich nicht ganz einsehen kann, warum du hier "protected" gesetzt hast

      Weil er die Variable nicht public machen wollte, trotzdem aber
      die Verwendung durch eine ableitende Klasse ermöglichen wollte, was
      mit private nicht gehen würde. "protected" ist hier also perfekt.
      (Der Zugriff ist dann natürlich nur über öffentliche Getter und
      Setter möglich -- klassenintern natürlich auch ohne.)

      public Kreis(double x, double y, double radius)
      Das ist aber problematisch. Du hast bereits deine Klassendefinition vorgenommen, und jetzt willst du noch eine Methode "Kreis" reinbasteln? Nenne die Methode anders, dann könnte es getrost so weitergehen:

      Ääh, Christoph, bist du dir sicher, was du da schreibst? ;-)

      Er definiert hier einen Konstruktor für seine Kreis-Klasse, der eben
      den x-Wert, den y-Wert und den Radius des Kreises entgegen nimmt.

      Folgendes ist absolut korrekt.

      super(x, y);

      Hier ruft er den Konstruktor der Super-
      Klasse auf und übergibt dem den x- und y-Wert. (Er spart sich damit
      die Wiederholung des Codes, der schon im Konstruktor der Super-
      Klasse steht. Das ganze ist die Anwendung des Vererbungsprinzip und
      so absolut sinnvoll und gewollt.)

      this.radius = radius;
      Das ist nicht ganz einleuchtend, könnte aber funktionieren.

      Das ist gängige Praxis und absolut korrekt.

      Oder ist das schon völliger blödsinn?

      Nein, das ist alles genau so, wie es die Aufgabenstellung erfordert
      und wie es von dir umgesetzt werden soll. Du hast es (soweit)
      verstanden!

      Gruß
      Slyh

      --
      Es gibt 10 Arten von Menschen. Solche, die das Binärsystem verstehen, und solche, die es nicht verstehen.
      1. Hi Slyh,

        Weil er die Variable nicht public machen wollte, trotzdem aber
        die Verwendung durch eine ableitende Klasse ermöglichen wollte, was
        mit private nicht gehen würde. "protected" ist hier also perfekt.
        (Der Zugriff ist dann natürlich nur über öffentliche Getter und
        Setter möglich -- klassenintern natürlich auch ohne.)

        Wenn sich der Text in der Klammer auf den 'private' Modifizierer bezieht: ja. (**)
        Wenn sich der Text in der Klammer auf den 'protected' Modifizierer bezieht: dann ist der direkte Zugiff per voll-qualifiziertem Feldidentifikator (trivial Feldname) in allen Klassen desselben Packages (wie bei 'default'-Sichtbarkeit, die bei Fehlen eines expliziten Modifizierers angewandt wird) und allen abgeleiteten Klassen der deklarierenden Klasse möglich.

        **: Ich gehe davon aus, dass Du Dich tatsächlich darauf bezogen hattest. Die kleine Korrektur nur, um weitere unnötige Verwirrung bei einem Lernenden zu vermeiden...

        Viele Grüße,
        Martin Jung

        1. Hallo Martin,

          um ehrlich zu sein, weiß ich nicht mehr, worauf ich mich beziehen
          wollte. So wie sich das liest, beziehe ich mich wohl aber tatsächlich
          auf das protected. Und somit ist dein Einwand absolut berechtigt und
          korrekt. Asche auf mein Haupt!

          Gruß
          Slyh

  2. Hi!

    /**
      *Kreis.java
      *Klasse, die von Punkt erben tut
      */

    public class Kreis extends Punkt {
       protected double radius;

    public Kreis(double x, double y, double radius){
      super(x, y);
         this.radius = radius;
         //text();
         //toString();
       }
     Oder ist das schon völliger blödsinn?

    Nein, das ist genau richtig so. Nur fehlt noch etwas. Die Methoden text() und toString() musst Du noch überschreiben, damit sie die richtigen Informationen über den Kreis liefern (aber Du hast ja auch nicht den gesamten Code geliefert, also wirst Du das sicher schon da drin stehen haben).
    Und eine Sache verstehe ich noch nicht: die text()-Methode ist doch überflüssig, warum machst Du das nicht alles in toString()?

    VG Simon

    --
    Die Jugend ist viel zu schade für die jungen Leute.
  3. hi!

    Nun soll ich noch 3 weitere Klassen Quadrat.java, Rechteck.java
    und Kreis.java, die von der Klasse Punkt direkt oder indirekt
    abgeleitet werden programmieren.

    Ohne jetzt groß auf die Aufgabe selbst einzugehen, möchte ich noch
    anmerken, dass das ziemlich grundlegende Vorgaben für das Design einer
    Objektstruktur verletzt. Ein Quadrat, Rechteck oder Kreis ist nun
    mal kein Punkt, daher ist es Unfug, diese Klassen als Unterklasse
    von Punkt zu entwerfen.

    Vielleicht kannst du das ja der aufgabenstellenden Person ausrichten...
    ;)

    bye, Frank!

    --
    Never argue with an idiot. He will lower you to his level and then
    beat you with experience.
    1. Moin!

      Ohne jetzt groß auf die Aufgabe selbst einzugehen, möchte ich noch
      anmerken, dass das ziemlich grundlegende Vorgaben für das Design einer
      Objektstruktur verletzt. Ein Quadrat, Rechteck oder Kreis ist nun
      mal kein Punkt, daher ist es Unfug, diese Klassen als Unterklasse
      von Punkt zu entwerfen.

      Jupp, da stimme ich Dir voll zu. Gut, es geht in der Aufgabe darum, die *Technik* der Vererbung in der jeweiligen Sprache zu erlernen, das ist klar. Aber ich frage mich, ob solche (immer wiederkehrenden) Beispiele nicht auch dazu beitragen, ein schlechtes Gefuehl fuer OO-Designs zu entwickeln.

      So long

      --
      Bier trinken fetzt!!!
      1. Hallo,

        Jupp, da stimme ich Dir voll zu. Gut, es geht in der Aufgabe darum, die *Technik* der Vererbung in der jeweiligen Sprache zu erlernen, das ist klar. Aber ich frage mich, ob solche (immer wiederkehrenden) Beispiele nicht auch dazu beitragen, ein schlechtes Gefuehl fuer OO-Designs zu entwickeln.

        Ziemlich sicher, ja.
        Wir haben damals eine sehr ähnliche Aufgabe erhalten. Nur war dort die
        Vaterklasse nicht Punkt, sondern Shape. Die Klasse hatte dann beispiels-
        weise eine Methode, mit der das umschließende Rechteck (Rectangle)
        ermittelt werden konnte, der Mittelpunkt usw. Davon wurde dann
        ein Rechteck abgeleitet und von Rechteck wiederum Quadrat usw.
        Das ist bei weitem sinnvoller und entspricht dem objektorienterten
        Ansatz.

        Was mir bei dem von molchi vorgegebenen Code (Klasse Punkt) noch
        ziemlich negativ auffällt, ist diese ganze Geschichte mit
          return new String("blub");

        Mir ist zwar klar, daß der Lehrer/Professor den Schülern/Studenten
        damit klar machen wollte, daß ein String auch nichts anderes als
        ein Objekt ist. Trotzdem halte ich den Ansatz für schlecht. Wieso
        sollte ich jemandem etwas beibringen, das unter realen Bedingungen
        so gar nicht gemacht wird. Ein deutlicher Hinweis darauf, daß beim
        Verwenden von >>return "blub";<< intern nichts anderes passiert als

        return new String("blub");<< wäre meiner Meinung nach absolut

        ausreichend. Für mein Verständnis hatte es damals zumindest gereicht.
        In dem Zusammenhang noch sowas wie >>"blub".length();<< gezeigt,
        vielleicht >>new String("blub").length();<< gegenübergestellt, und
        auch der letzte sollte es begriffen haben. Oder bin ich da zu
        optimistisch?

        Gruß
        Slyh

        --
        Es gibt 10 Arten von Menschen. Solche, die das Binärsystem verstehen, und solche, die es nicht verstehen.