Vererbung: Unterschied zwischen den Versionen

Aus SibiWiki
Zur Navigation springen Zur Suche springen
(Die Seite wurde neu angelegt: „=Allgemeines= ''Der folgende Text ist aus [http://de.wikipedia.org/wiki/Vererbung_(Programmierung) Wikipedia] und gekürzt.''' Vererbung dient dazu, aufbauend …“)
 
Zeile 103: Zeile 103:


'''Erläuterungen:'''
'''Erläuterungen:'''
* <code>Fachbuch</code> '''ist-ein''' <code>Buch</code>; für <code>Hoerbuch</code> gilt dasselbe.
* Das Schlüsselwort für Vererbung ist <u><code>extends</code></u>; damit wird eine Klasse zur Subklasse.
* Das Schlüsselwort für Vererbung ist <u><code>extends</code></u>; damit wird eine Klasse zur Subklasse.
* Im Konstruktor der Subklassen muss zuerst mit dem Schlüsselwort <u><code>super(...)</code></u> der Konstruktor der Superklasse aufgerufen werden.
* Im Konstruktor der Subklassen muss zuerst mit dem Schlüsselwort <u><code>super(...)</code></u> der Konstruktor der Superklasse aufgerufen werden.
** D.h. zum Beispiel für <code>Fachbuch<code>: Um ein Objekt vom Typ <code>Fachbuch</code> zu erzeugen, muss erst der Konstruktor von <code>Buch</code> aufgerufen werden; das ist auch inhaltlich wichtig, denn nur so können <code>titel</code> und <code>autor</code> richtig eingetragen werden.
** D.h. zum Beispiel für <code>Fachbuch</code>: Um ein Objekt vom Typ <code>Fachbuch</code> zu erzeugen, muss erst der Konstruktor von <code>Buch</code> aufgerufen werden; das ist auch inhaltlich wichtig, denn nur so können <code>titel</code> und <code>autor</code> richtig eingetragen werden.
* Mit <code><u>super.info()</u></code> greifen die Subklassen auf die Methode <code>info()</code> der Superklasse zu. Das nennt man '''[[Polymorphie]]'''.
* Mit <code><u>super.info()</u></code> greifen die Subklassen auf die Methode <code>info()</code> der Superklasse zu. Das nennt man '''[[Polymorphie]]'''.
=Vererbung vs. Hat-Beziehung=
In manchen Fällen darf man Vererbung nicht verwenden, obwohl es sich um eine "ist-ein"-Beziehung handelt.
Im Hinblick auf das Zentralabitur ist vor allem das folgende Kriterium wichtig:
* Können Methoden der Superklasse die Struktur der Subklasse zerstören?
In diesen Fällen ist eine Modellierung mit einer Hat-Beziehung vorzuziehen.
== Beispiele ==
[[File:Vererbung-vs-hat-beziehung.png|thumb|Vererbung vs. Hat-Beziehung |817px]]
'''Erläuterung zur Vererbung (=links):'''
* Der Klasse <code>Quadrat</code> steht die Methode <code>aendereBreite(double pBreite)</code> zur Verfügung, denn sie erbt diese Methode von der Superklasse <code>Rechteck</code>.
* Wenn für ein Quadrat die Methode <code>aendereBreite(...)</code> aufgerufen wird, dann wird die Struktur des Quadrats '''zerstört''' - ''denn es ist dann kein Quadrat mehr''!
* D.h. Vererbung darf man hier '''nicht''' verwenden, obwohl inhaltlich eindeutig einen "ist-ein"-Beziehung vorliegt!
'''Erläuterung zur hat-Beziehung (=rechts):'''
Um die Funktionalität des Rechtecks (u.a.: die Flächenberechnung)  trotzdem nutzen zu können, wird zwischen <code>Quadrat</code> und <code>Rechteck</code> eine hat-Beziehung hergestellt.
In der Implementierung sieht die Klasse <code>Quadrat</code> dann so aus.
* <code>Quadrat</code> greift überall auf die entsprechende Funktionalität von <code>Rechteck</code> zu.
* Das <code>Rechteck</code> kann das <code>Quadrat</code> nicht zerstören, denn <code>meinRechteck</code> ist privat, also für den Nutzer von Objekten der Klasse <code>Quadrat</code> nicht sichtbar!
<code>
  public class Quadrat{
    private Rechteck meinRechteck;
    public Quadrat(double pSeite){
      meinRechteck = new Rechteck(pSeite, pSeite);
    }
    public void aendereSeite(double pSeite){
      meinRechteck.aenderLaenge(pSeite);
      meinRechteck.aendereBreite(pSeite);
    }
    public double gibSeite(){
      return meinRechteck.gibLaenge();
    }
    public double flaeche(){
      return meinRechteck.gibFlaeche();
    }
  }
</code>

Version vom 8. April 2014, 19:44 Uhr

Allgemeines

Der folgende Text ist aus Wikipedia und gekürzt.' Vererbung dient dazu, aufbauend auf existierenden Klassen neue zu schaffen. Eine neue Klasse kann dabei eine Erweiterung oder eine Einschränkung der ursprünglichen Klasse sein.

  • Die vererbende Klasse wird meist Superklasse, Basisklasse oder Oberklasse genannt. In diesem Artikel wird immer von Superklasse genannt.
  • Die erbende Klasse wird Subklasse, abgeleitete Klasse oder Unterklasse genannt. In diesem Artikel wird sie immer Subklasse genannt.
  • Den Vorgang des Erbens nennt man Ableitung.
  • In UML wird eine Vererbungsbeziehung durch einen Pfeil mit einer dreieckigen (leeren!) Spitze dargestellt, der von der abgeleiteten Klasse zur Basisklasse zeigt.
  • Der Subklasse stehen alle public-Methoden und public-Attribute der Superklasse zur Verfügung.
  • Geerbte Attribute und Methoden werden in der Darstellung der Subklasse nicht wiederholt. Das gilt sowohl für das UML-Diagramm als auch für den Java-Quelltext.
  • Abgeleitete Klasse und Basisklasse stehen typischerweise in einer "ist-ein"-Beziehung zueinander.

Beispiel

Klassendiagramm
  • Fachbuch und Hoerbuch erben von Buch.
  • Buch ist die Superklasse
  • Fachbuch und Hoerbuch sind die Subklassen.
  • Fachbuch und Hoerbuch verfügen über alle public-Methoden von Buch.

Implementierung

public class Buch{
  private String titel;
  private String autor;
  
  public Buch(String pAutor, String pTitel){
     autor = pAutor;
     titel = pTitel;
  }
  
  public String gibTitel(){
     return titel;
  }
  
  public String gibAutor(){
     return autor;
  }
  
  /**
   * info ist eine polymorphe Methode!
   */
  public String info() {
     String ergebnis = "Autor: "+autor+"; Titel: "+titel;
     return ergebnis;
  }
}
public class Fachbuch extends Buch{
  private String kategorie;
  
  public Fachbuch(String pAutor, String pTitel, String pKategorie){
     // den Konstruktor von Buch aufrufen!
     super(pAutor, pTitel);
     kategorie = pKategorie;
  }
  
  public String gibKategorie(){
     return kategorie;
  }
  
  /**
   * info() ist eine polymorphe Methode
   */
  public String info(){
     // erst mal die info der Klasse Buch abfragen!
     String ergebnis = super.info();
     ergebnis += "; Kategorie: "+kategorie;
     return ergebnis;
  }
}
public class Hoerbuch extends Buch{
  private double dauer;
  private String sprecher;
  
  public Hoerbuch(String pAutor, String pTitel, double pDauer, String pSprecher){
     // den Konstruktor von Buch aufrufen!
     super(pAutor, pTitel);
     dauer = pDauer;
     sprecher = pSprecher;
  }
  
  public double gibDauer(){
     return dauer;
  }
  
  public String gibSprecher(){
     return sprecher;
  }
  
  /**
   * info() ist eine polymorphe Methode.
   */
  public String info(){
     // erst mal die info der Klasse Buch abfragen!
     String ergebnis = super.info();
     ergebnis += "; Dauer: "+dauer+" Sprecher: "+sprecher;
     return ergebnis;
  }
}

Erläuterungen:

  • Fachbuch ist-ein Buch; für Hoerbuch gilt dasselbe.
  • Das Schlüsselwort für Vererbung ist extends; damit wird eine Klasse zur Subklasse.
  • Im Konstruktor der Subklassen muss zuerst mit dem Schlüsselwort super(...) der Konstruktor der Superklasse aufgerufen werden.
    • D.h. zum Beispiel für Fachbuch: Um ein Objekt vom Typ Fachbuch zu erzeugen, muss erst der Konstruktor von Buch aufgerufen werden; das ist auch inhaltlich wichtig, denn nur so können titel und autor richtig eingetragen werden.
  • Mit super.info() greifen die Subklassen auf die Methode info() der Superklasse zu. Das nennt man Polymorphie.

Vererbung vs. Hat-Beziehung

In manchen Fällen darf man Vererbung nicht verwenden, obwohl es sich um eine "ist-ein"-Beziehung handelt. Im Hinblick auf das Zentralabitur ist vor allem das folgende Kriterium wichtig:

  • Können Methoden der Superklasse die Struktur der Subklasse zerstören?

In diesen Fällen ist eine Modellierung mit einer Hat-Beziehung vorzuziehen.

Beispiele

Vererbung vs. Hat-Beziehung

Erläuterung zur Vererbung (=links):

  • Der Klasse Quadrat steht die Methode aendereBreite(double pBreite) zur Verfügung, denn sie erbt diese Methode von der Superklasse Rechteck.
  • Wenn für ein Quadrat die Methode aendereBreite(...) aufgerufen wird, dann wird die Struktur des Quadrats zerstört - denn es ist dann kein Quadrat mehr!
  • D.h. Vererbung darf man hier nicht verwenden, obwohl inhaltlich eindeutig einen "ist-ein"-Beziehung vorliegt!


Erläuterung zur hat-Beziehung (=rechts):

Um die Funktionalität des Rechtecks (u.a.: die Flächenberechnung) trotzdem nutzen zu können, wird zwischen Quadrat und Rechteck eine hat-Beziehung hergestellt.

In der Implementierung sieht die Klasse Quadrat dann so aus.

  • Quadrat greift überall auf die entsprechende Funktionalität von Rechteck zu.
  • Das Rechteck kann das Quadrat nicht zerstören, denn meinRechteck ist privat, also für den Nutzer von Objekten der Klasse Quadrat nicht sichtbar!

 public class Quadrat{

   private Rechteck meinRechteck;

   public Quadrat(double pSeite){
      meinRechteck = new Rechteck(pSeite, pSeite);
   }

   public void aendereSeite(double pSeite){
      meinRechteck.aenderLaenge(pSeite);
      meinRechteck.aendereBreite(pSeite);
   }

   public double gibSeite(){
      return meinRechteck.gibLaenge();
   }

   public double flaeche(){
      return meinRechteck.gibFlaeche();
   }
 }