Bergervei/Java-Klassen

Aus ProgrammingWiki

Wiki-Quelltext dieser Seite.

<language>Java</language>
== Einführung in die Objektorientierte Programmierung ==

=== Technische Voraussetzungen ===

Zur Objektorientierten Programmierung ist die Policy-Datei
* <tt>JavaPolicy.class</tt>
erforderlich. Entsprechenden Hinweise findet man unter: [[JavaPolicy]].

=== Definition einer Klasse ===

Wir definieren die (Objekt-)Klasse ''Bruch'':

<code id="513c5b7b51f5c">
public class Bruch {

 protected int z;
 protected int n;

 public Bruch(int z, int n) {
  if (n < 0) {
   z = -z; n = Math.abs(n);
  }
  this.z = z;
  this.n = n;
 }

 public int Zaehler() {
  return z;
 }

 public int Nenner() {
  return n;
 }

 public double Dezimal() {
  return z/n;
 }

 public void Ausgabe() {
  System.out.println(z + "/" + n);
 }
 
 public void Addition(Object Summand) {
  z = z * Summand.Nenner() + n * Summand.Zaehler();
  n = n * Summand.Nenner();
 }

 public void Subtraktion(Object Subtrahend) {
  z = z * Subtrahend.Nenner() - n * Subtrahend.Zaehler();
  n = n * Subtrahend.Nenner();
 }
 
 public void Multiplikation(Object Faktor) {
  z = z * Faktor.Zaehler();
  n = n * Faktor.Nenner();
 }

 public void Division(Object Divisor) {
  z = z * Divisor.Nenner();
  n = n * Divisor.Zaehler();
  if (n < 0) {
   z = -z; n = Math.abs(n);
  }
 }

 public void Reziprok() {
  int h;
  h = z; z = n; n = h;
  if (n < 0) {
   z = -z; n = Math.abs(n);
  }
 }
}
</code>

=== Instanzen einer Klasse ===

Zunächst erzeugen wir die Instanzen ''Bruch1'' und ''Bruch2'' der Klasse ''Bruch'' und geben sie mit der Methode ''Ausgabe'' aus:

<code id="513c5b7b51fce">
Bruch1 = new Bruch(1, 2);
Bruch2 = new Bruch(3, 4);
</code>

<run id="513c5b7b52176">
System.out.print("Bruch1: "); Bruch1.Ausgabe();
System.out.print("Bruch2: "); Bruch2.Ausgabe();
</run>

=== Kapselung, Eigenschaften und Methoden einer Klasse === 

Eine dritte Instanz ''Bruch3'' soll die Zähler-Eigenschaft <tt>'''z'''</tt> und die Nenner-Eigenschaften <tt>'''n'''</tt> der ersten Instanz ''Bruch1'' erhalten. Diese Eigenschaften sind streng ''gekapselt'', d.h. ein direkekter Zugriff ist nicht möglich. Wir müssen deshalb die Methoden ''Zaehler'' und ''Nenner'' benutzen.<br /> Anschließend wird die Methode ''Addition'' mit der Instanz ''Bruch2'' ausgeführt: 

<code id="513c5b7b52033">
Bruch3 = new Bruch(Bruch1.Zaehler(), Bruch1.Nenner());
Bruch3.Addition(Bruch2);
</code>

<run id="513c5b7b521d4">
System.out.print("Bruch3: "); Bruch3.Ausgabe();
</run>

=== Vererbung ===

Es fällt auf, dass eine Methode zum vollständigen Kürzen von Brüchen in der Klasse ''Bruch'' fehlt.<br />
Wir leiten aus ihr die Unterklasse ''GekuerztBruch'' ab, die zunächst alle Eigenschaften und Methoden der Oberklasse ''erbt''. Schließlich wird sie durch die Methode ''Kuerzen'' ergänzt:
 
<code id="513cdb3bdd2fa">
public class GekuerztBruch extends Bruch {

 public GekuerztBruch(int z, int n) {
  super(z, n);
 }

 private int ggT(int m, int n) {
  if (n == 0)
   return m;
  else
   return ggT(n, m % n);
 }

 public void Kuerzen() {
  int teiler = Math.abs(ggT(z, n));
  z = z / teiler;
  n = n / teiler;
 }
}
</code>

<code id="513c5b7b520f6">
Bruch4 = new GekuerztBruch(Bruch3.Zaehler(), Bruch3.Nenner());
Bruch4.Kuerzen();
</code>

<run id="513c5b7b52241">
System.out.print("Bruch4: "); Bruch4.Ausgabe();
</run>

=== Polymorphie ===

Wir leiten von der Unterklasse ''GekuerztBruch'' erneut eine Unterklasse ab und nennen sie ''GemischtBruch'':

<code id="513ca5a267739">
public class GemischtBruch extends GekuerztBruch {

 public GemischtBruch(int z, int n) {
  super(z, n);
 }

 public void Ausgabe() {
  int g; int z0; int n0;
  double quotient = z / n;
  if (quotient < 0)
   g = (int)Math.ceil(quotient);
  else
   g = (int)Math.floor(quotient);
  if (g == 0)
   System.out.println(z + "/" + n);
  else {
   z0 = Math.abs(z % n);
   n0 = n;
   System.out.println(g + " " + z0 + "/" + n0);
  }
 } 
}
</code>

<code id="513c82600c2f4">
Bruch5 = new GemischtBruch(Bruch4.Zaehler(), Bruch4.Nenner());
</code>

<run id="513c82600c362">
System.out.print("Bruch5: "); Bruch5.Ausgabe();
</run>

Wir stellen fest: Innerhalb einer Klassenhierarchie können Methoden mit gleichen Bezeichnern und gleicher Signatur verschiedene Wirkungen hervorrufen. Diese Vielschichtigkeit heißt ''Polymorphie''.