Benutzer-Werkzeuge

Webseiten-Werkzeuge


techniken:objektorientjava

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen gezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
techniken:objektorientjava [2016/07/06 13:27]
fbonowski
techniken:objektorientjava [2016/07/14 14:43] (aktuell)
c.jaedicke [Konventionen]
Zeile 103: Zeile 103:
 In der Praxis macht das insbesondere bei Zuweisungen von Variablen einen Unterschied:​ In der Praxis macht das insbesondere bei Zuweisungen von Variablen einen Unterschied:​
 === Bei primitiven Variablen... === === Bei primitiven Variablen... ===
- 
   * Wird der Inhalt der Variable kopiert. ​   * Wird der Inhalt der Variable kopiert. ​
   * Beide Variablen haben danach getrennte Kopien des selben Wertes.   * Beide Variablen haben danach getrennte Kopien des selben Wertes.
   * Veränderungen der einen Variable haben nach einer Zuweisung keinen Einfluss auf den Wert der anderen Variable   * Veränderungen der einen Variable haben nach einer Zuweisung keinen Einfluss auf den Wert der anderen Variable
-=== Bei Klassenvariablen ​... ===+=== Bei Variablen mit Klassentyp... ===
   * Wird nur die Referenz / Speicheradresse kopiert.   * Wird nur die Referenz / Speicheradresse kopiert.
   * Beide Variablen verweisen danach auf das **//​selbe//​** Objekt.   * Beide Variablen verweisen danach auf das **//​selbe//​** Objekt.
   * Veränderungen des Objektes über die eine Variable wirken sich dementsprechend auf das aus, was über die andere Referenzvariable ausgelesen werden kann.   * Veränderungen des Objektes über die eine Variable wirken sich dementsprechend auf das aus, was über die andere Referenzvariable ausgelesen werden kann.
  
 +Hier ein Beispiel, welches das unterschiedliche Verhalten von Variablen mit primitiven und Klassentypen:​
 <code Java> <code Java>
-//primitive variablen ​enthalten einen Wert.+//Primitive Variablen ​enthalten einen Wert, der bei Zuweisungen kopiert wird:
 int a=1; int a=1;
 int b=2; int b=2;
-a=b;         // ​der Inhalt ​vonb b (2) wird in a kopiert. +a=b;         // ​Der Inhalt ​von b (2) wird in a kopiert. 
-println(a); ​ // ausgabe ​"​2"​ +println(a); ​ // Ausgabe ​"​2"​ 
-println(b); ​ // ausgabe ​"​2"​ +println(b); ​ // Ausgabe ​"​2"​ 
-b=3;         // ​der Inhalt von b wird mit "​3"​ überschrieben +b=3;         // ​Der Inhalt von b wird mit "​3"​ überschrieben, a bleibt davon unberührt. 
-println(a); ​ // ausgabe ​"​2"​ (unverändert +println(a); ​ // Ausgabe ​"​2"​ (unverändert) 
-println(b); ​ // ausgabe ​"​3"​+println(b); ​ // Ausgabe ​"​3"​
  
-//Klassenvariablen ​enthalten eine Referenz auf ein Objekt: +//Variablen mit Klassentyp ​enthalten eine Referenz auf ein Objekt: 
-Robot +Robot robotOne=new Robot(); // ein erster Roboter 
-</code>+Robot robotTwo=new Robot(); ​// ein zweiter Roboter
  
 +robotOne.direction=PI; ​ // der erste Roboter schaut nach links
 +robotTwo.direction=0; ​  // der zweite Roboter schaut nach rechts
  
 +robotOne=robotTwo;​ // RobotOne zeigt auch jetzt auf das Objekt, auf das vorher nur RobotTwo gezeigt hat.
 +// Das Objekt, auf das robotOne vorher gezeigt hat, wird vergessen. (und vom Garbage Collector entsorgt)
  
-===== Konventionen ===== 
  
 +robotTwo.direction=PI/​2;​ // Ändere die Richtung des Objekts, auf das die Referenz in robotTwo zeigt.
 +println(robotOne.direction);​ // Da beide Variablen das gleiche Objekt referenzieren,​ kommt auch hier PI/2 heraus!
 +</​code>​
  
-Bei der Benennung von Methoden sollte man sich an zwei grundsätzliche Konventionen halten: ​ 
-  - Der Name der Methode fängt mit einem kleinen Buchstaben an und Namen welche mehrere Worte beinhalten fangen beim zweiten Wort mit einem Großbuchstaben an.  
-  - Der Name sollte beschreiben wie die Methode mit dem Objekt interagiert. 
  
-Unsere Klasse bekommt zwei weitere Methodeneine um den Roboter an seiner aktuellen Position zu zeichnen und eine um den Roboter um einen gewissen Winkel zu drehen.+===== Ein fertiges Programm ===== 
 +Zum Abschluss nochmal ein kleines Programmin dem alles, was bisher passiert ist, angewandt wird:
  
-<​code ​java>+<​code ​Java>
 class Robot { // Deklaration der Klasse Robot class Robot { // Deklaration der Klasse Robot
- +  float posX = 100;     //Die x-Position des Roboters in Pixel 
-  ​int dRobot ​50   //Der Durchmesser ​des Roboters in Pixel +  ​float posY 100    ​//Die y-Position ​des Roboters in Pixel 
-  float direction = PI;  //Die Richtung in die der Roboter schaut ​ +  float direction= PI;  //Die Richtung in die der Roboter schaut, in Bogenmaß, gegen den Uhrzeigersinn,​ relativ zur X-Achse. 
-                      //(PI (links)da der Winkel ​in Bogenmaß ​angegeben wird) +                        // (PI  => der Roboter schaut nach links) 
-  float posX = 100;   //Die x-Position des Roboters in Pixel + 
-  float posY 100;   //Die y-Position des Roboters in Pixel +
-  +
   //Diese Methode zeichnet einen Roboter ​   //Diese Methode zeichnet einen Roboter ​
   //an seiner aktuellen Position und Ausrichtung.   //an seiner aktuellen Position und Ausrichtung.
   void drawRobot(){ //"​void"​ bedeutet dass es keinen Rückgabewert gibt   void drawRobot(){ //"​void"​ bedeutet dass es keinen Rückgabewert gibt
-    ​// Zeichne einen Kreis an der Position des Roboters. +    ellipse(posX,​posY,​20,20); // Zeichne ​einen Kreis an der Position ​des Roboters. 
-    ​ellipse(posX,​posY,​dRobot,dRobot); +    line(posX,​posY,​posX+cos(direction)*50,​ posY+sin(direction)*50);​// Zeichne eine Linie welche die Orientierung des Roboters angibt.
-    ​// Zeichne ​eine Linie welche die Orientierung ​des Roboters ​angibt+
-    line(posX,​posY,​posX+cos(direction)*50,​ posY+sin(direction)*50);​+
   }   }
-  ​+ 
   //Die moveForward-Funktion verändert die Position so, wie es einen Schritt nach vorne entspricht.   //Die moveForward-Funktion verändert die Position so, wie es einen Schritt nach vorne entspricht.
   void moveForward(float distance){   void moveForward(float distance){
Zeile 161: Zeile 161:
     posY = posY+sin(direction)*distance;​ // zugegriffen werden. (Sie sind im Objekt quasi "​lokal"​)     posY = posY+sin(direction)*distance;​ // zugegriffen werden. (Sie sind im Objekt quasi "​lokal"​)
   }   }
-  ​ 
-  //Diese Methode dreht den Roboter um einen gewissen Winkel ​ 
-  //welcher von "​winkelaenderung"​ vorgegeben wird. 
-  // Die Methode bekommt einen Übergabeparameter vom Typ "​float"​. 
-  void turnRobot(float angle){ ​ 
-    this. direction += angle; 
-  } 
-  ​ 
 } }
  
-</code>+Robot myRobot; ​// deklariere eine Referenz auf einen Roboter (sie verweist in diesem Moment ins Leere)
  
-Jetzt können wir die fertige Klasse verwenden. Um dies in Processing auf eine möglichst übersichtliche weise zu tun sollte ein neuer Tab geöffnet werden: 
  
-{{:​Techniken:​processingtab.jpg?​nolink|}}+// Das Processing "​setup"​ 
 +void setup(){ 
 +  myRobot=new Robot(); 
 +}
  
-In diesem neuen Tab speichert ihr eure Klasse. 
-===== Klasse verwenden in Processing ===== 
  
-Klassen geben den Rahmen vor für unsere Objekte. Wie ihr bereits kennengelernt habt, kann man aus einer Klasse ein Objekt erzeugen durch den „new“ -Operator. +// Das Processing ​"setup
-Ein Programm welches in Processing geschrieben wurde kann die "​Robot"​-Klasse z.B. folgendermaßen einsetzen:​ +void draw(){ 
- +  background(235); ​      ​// Male den Hintergrund des Fensters neu an... 
-<code java> +  myRobot.drawRobot();   ​// Zeichne in das nun leere Fenster den Roboter 
- +  myRobot.moveRobot();   ​// Diese Funktion bewegt den Roboter ein wenig. 
-//Erstellt ein global verfügbares Objekt vom Typ "Robot",  +  myRobot.direction+=PI/​200; // drehe den Roboter ​ein Stück gegen den Uhrzeigersinn
-//wie "​int"​ oder "​double",​ und geben ihm den Namen "​myRobot"​. +
-Robot myRobot; +
- +
-void setup() { +
-  // Festlegen der Fenstergröße +
-  size(500,​500);​ +
-  // Festlegen der Hintergrundfarbe +
-  background(235);​ +
-  ​//Initialisiert das "​Robot"​ Objekt +
-  myRobot ​= new Robot(); +
-+
- +
-void draw() { +
-  ​//Zu beginn jeder draw-Iteration wird das Fenster ​zurückgesetzt. +
-  background(235);​ +
-  //Das Robot-Objekt verfügt über eine Funktion die den Roboter ​malt. +
-  myRobot.drawRobot(); +
-  ​//Diese Funktion bewegt den Roboter ein wenig. +
-  myRobot.moveRobot(); +
-  ​//Dieser Funktionsaufruf sorgt dafür das der Roboter ​nach jeder translation  +
-  //um PI/200 gedreht wird. +
-  myRobot.turnRobot(PI/​200);​+
 } }
  
 </​code>​ </​code>​
  
-===== Klassen für Fortgeschrittene ​=====+===== Konventionen ​=====
  
-In diesem Abschnitt ist das Beispiel von oben nochmals aufgeführt in einer "​best-practise"​-Version. Hierbei ändern sich zwei wesentliche Dinge: 
  
-  - Statt einfachen Kommentaren werden die Konventionen ​der JavaDoc angewandt. Die JavaDoc ist eine Documentation des Codes welche automatisch aus den Kommentaren generiert wird sofern diese der vorgegebenen Konvention entspricht. Wie diese Konvention im Einzelnen aussieht erfahrt ihr z.B. hier[[https://​www.wecowi.de/​wiki/​Javadoc|https://​www.wecowi.de/​wiki/​Javadoc]]. +Bei der Benennung von Methoden sollte man sich an zwei grundsätzliche ​Konventionen ​halten:  
-  - Diese Version enthält Konstruktoren. Mit Konstruktoren können die Klassenvariablen direkt beim erstellen eines Objektes modifiziert werden. ​Der "​default"​-Konstruktor ist auch dann vorhanden wenn er nicht explizit definiert wurde, deshalb konnte in der einfachen Version ein Objekt erstellt werden ​mit //new Robot()//. In Java können Konstruktoren ​und Methoden im allgemeinen überladen werden. Das bedeutet es darf mehrere ​Methoden ​mit demselben Namen geben solange sich die Übergabeparameter bzw. Rückgabetyp unterscheiden. Im folgenden Beispiel sind zwei Konstruktoren enthalten.+  - Der Name der Methode fängt ​mit einem kleinen Buchstaben an und Namen welche ​mehrere ​Worte beinhalten fangen beim zweiten Wort mit einem Großbuchstaben an.  
 +  - Der Name sollte beschreiben wie die Methode mit dem Objekt interagiert.
  
-<code java> +Unsere ​Klasse ​bekommt zwei weitere Methoden, eine um den Roboter an seiner aktuellen Position zu zeichnen und eine um den Roboter um einen gewissen Winkel zu drehen.
-class Robot { // Deklaration der Klasse ​Robot+
  
-  /** Der Durchmesser des Roboters. */ +===== Tabs  in Processing ===== 
-  int dRobot; +Jetzt können wir die fertige Klasse verwendenUm dies in Processing auf eine möglichst übersichtliche weise zu tun sollte ​ein neuer Tab geöffnet werden:
-  /** Die Richtung in die der Roboter schaut. */ +
-  float winkel; +
-  /** Die x-Position des Roboters. */ +
-  float posX; +
-  /** Die y-Position des Roboters. */ +
-  float posY; +
-   +
-  /** +
-   * Der "​default"​-Konstruktor erstellt ein Roboter-Objekt mit Standardwerten für alle notwendigen Parameter. +
-   */ +
-  public Robot() { +
-    this.dRobot ​50; +
-    this.winkel ​PI; +
-    this.posX ​100; +
-    this.posY ​100; +
-  +
-  /** +
-   * Dieser Konstruktor erstellt ein Roboter-Objekt mit allen notwendigen Parametern,​ +
-   * entsprechend der Vorgabe durch die Eingabeparameter. +
-   */ +
-  public Robot(int dRobot, float winkel, float posX, float posY) { +
-    this.dRobot ​dRobot; +
-    this.winkel ​winkel; +
-    this.posX ​posX; +
-    this.posY ​posY; +
-  } +
-   +
-  /** +
-   * Diese Methode zeichnet einen Roboter an seiner aktuellen Position und Ausrichtung. +
-   */ +
-  void drawRobot(){ +
-    // Zeichne einen Kreis an der Position des Roboters. +
-    ellipse(posX,​posY,​dRobot,​dRobot);​ +
-    // Zeichne ​eine Linie welche die Orientierung des Roboters angibt. +
-    line(posX,​posY,​posX+cos(winkel)*50,​ posY+sin(winkel)*50);​ +
-  } +
-   +
-  /** +
-   * Diese Methode bewegt einen Roboter ​ein kleines Stück in die Richtung in die er gerade schaut. +
-   */ +
-  void moveRobot(){ +
-    this.posX = this.posX+cos(this.winkel)*2;​ +
-    this.posY = this.posY+sin(this.winkel)*2;​ +
-  } +
-   +
-  /** +
-   * Diese Methode dreht den Roboter um einen gewissen Winkel welcher von "​winkelaenderung"​ vorgegeben wird. +
-   */ +
-  void turnRobot(float winkelaenderung){ +
-    this.winkel = winkel + winkelaenderung;​ +
-  } +
-   +
-+
-</​code>​ +
-===== Referenzvariablen =====+
  
-Variablen welche stellvertretend für ein Objekt verwendet werden, z.B. myRobot aus dem vorherigen Bsp., stellen lediglich eine Referenz auf das Objekt dar. Man kann die Variable also auch als die Speicheradresse des Objektes verstehen. Dieser Sachverhalt ist insbesondere dann von Bedeutung wenn ein Objekt kopiert werden soll. Die "​best-practise"​ ist das Anlegen eines "​copy"​-Konstruktors in jeder Klasse, dieser überträgt alle Attribute des zu kopierenden Objektes in ein neues Objekt:+{{:​Techniken:​processingtab.jpg?​nolink|}}
  
-<code java>+In diesem neuen Tab speichert ihr eure Klasse. 
 +===== Das ist noch nicht alles... ===== 
 +Mit dem, was bis hierhin besprochen wurde, könnt ihr schonmal einigermaßen Ordunung in euer Programm bringen und die von einer Library bereitgestellen Klassen benutzen.
  
-class DummyBean { +Für ein vollständiges Verständnis von Objektorientierung in Java fehlen noch:
-  String dummy; +
-  int yummyDummy;+
  
-  ​DummyBean(DummyBean dummyBeanToCopy) { +  ​* Zugriffssteuerung auf Memberfunktionen und Variablen durch **//​private,​ public, protected//​** 
-    this.dummy = dummyBeanToCopy.dummy;​ +  ​* Vererbung
-    this.yummyDummy = dummyBeanToCopy.yummyDummy;​ +
-  ​+
-}+
  
-</code>+Eure Programme werden besser lesbar, wenn ihr die folgenden "​Style-Konventionen"​ einhaltet:​ 
 +[[http://​www.oracle.com/​technetwork/​java/​codeconventions-135099.html]]
  
-Und können diesen Konstruktor entsprechend aufrufen: 
- 
-<code java> 
-//A Object of my DummyBean class 
-DummyBean myFirstDummy = new DummyBean();​ 
-//make a copy of the myFirstDummy object 
-DummyBean mySecondDummy = new DummyBean(myFirstDummy);​ 
-</​code>​ 
- 
-Kopiert man Objekte nicht auf diese Weise sondern durch: 
- 
-<code java> 
-//A Object of my DummyBean class 
-DummyBean myFirstDummy = new DummyBean();​ 
-//silly copy 
-DummyBean mySecondDummy = myFirstDummy;​ 
-</​code>​ 
-, dann wirken sich Änderungen an "​myFirstDummy"​ auch auf "​mySecondDummy"​ aus da beide Variablen auf das selbe Objekt verweisen. 
-===== Vererbung ===== 
  
-In Java kann unter Vererbung eine Spezialisierung einer bestehenden Klasse verstanden werden. Wir unterscheiden dazu in Super- und Subklassen. Die Superklasse (oder Elternklasse) beinhaltet eher allgemeine Attribute und Methoden. Die Klasse "​Stift"​ könnte z.B. Attribute für Stiftlänge,​ Stiftfarbe, usw. enthalten. Die Subklasse bekommt von der Superklasse alle Attribute und Methoden vererbt, erweitert dieses Set aber um eigene Attribute und Methoden. Z.B. könnte die Subklasse "​Kugelschreiber"​ das Attribut Stift eingefahren/​Stift ausgefahren hinzufügen und eine Methode die diesen Zustand verändert. 
  
-Eine ausführliche Beschreibung wie Vererbung funktioniert findet ihr hier: [[http://​www.java-tutorial.org/​vererbung.html|http://​www.java-tutorial.org/​vererbung.html]] 
techniken/objektorientjava.1467804471.txt.gz · Zuletzt geändert: 2016/07/06 13:27 von fbonowski