Zur Haupt­na­vi­ga­ti­on sprin­gen [Alt]+[0] Zum Sei­ten­in­halt sprin­gen [Alt]+[1]

Be­zie­hun­gen

Man un­ter­schei­det im We­sent­li­chen zwi­schen fol­gen­den Be­zie­hun­gen:

  • Ver­er­bung (Be­zie­hung zwi­schen Klas­sen) : Ein Crt­Bild­schirm ist ein Bild­schirm

  • Ag­gre­ga­ti­on (Be­zie­hun­gen zwi­schen Ob­jek­ten): Ein Fern­se­her hat einen Bild­schirm

  • As­so­zia­ti­on (Be­zie­hung zwi­schen Ob­jek­ten): Eine Fern­be­die­nung kennt einen Fern­se­her

Ver­er­bung (Spe­zi­al­sie­rung / Ge­ne­ra­li­sie­rung)

Mit die­ser Be­zie­hung haben wir uns im letz­ten Ab­schnitt schon be­schäf­tigt. Hier noch­mals in Kurz­form: Der Am­bi­light-Bild­schirm ist ein (spe­zi­el­ler) Bild­schirm. Somit be­sitzt (erbt) er alle At­tri­bu­te und Me­tho­den von der Klas­se Bild­schirm. Die Klas­se Bild­schirm ist eine Ver­all­ge­mei­ne­rung (Ge­ne­ra­li­sie­rung) der Klas­se Am­bi­light-Bild­schirm. Da die Klas­se Bild­schirm abs­trakt ist, Am­bi­light-Bild­schirm aber nicht, muss in der ab­ge­lei­te­ten Klas­se die Me­tho­de get­Typ() fest­ge­legt wer­den. In ihr kann es aber auch neue At­tri­bu­te (hier: um­ge­bungs­licht) und Me­tho­den geben. Mit dem Be­griff „Ver­er­bung“ wird also eine Struk­tur­be­zie­hung zwi­schen Klas­sen be­zeich­net.

Wenn man den Be­zie­hungs-Pfeil per Kon­text­me­nü ein­fügt, hat das lei­der keine Kon­se­quen­zen für den Quell­code, der dann ja in der Klas­sen­be­zeich­nung so aus­se­hen soll­te (siehe oben):

public class AmbilightBildschirm extends Bildschirm

Ag­gre­ga­ti­on

Die kon­kre­te Bild­röh­re ist Teil des Fern­se­hers, kann aber ohne ihn exis­tie­ren. Somit er­füllt die Be­zie­hung die Be­din­gung der Ag­gre­ga­ti­on. Wie kann man mit­tels Code eine sol­che Be­zie­hung rea­li­sie­ren? (Für die Pu­ris­ten: Man nennt die Be­zie­hung eine Kom­po­si­ti­on, wenn das Teil ohne das Ganze nicht exis­tiert. Bei­spiel: Bank­kun­de – Kun­den-Konto).
Hier ein Code-Aus­schnitt aus Fern­se­her mit den we­sent­li­chen Tei­len in Fett­druck:

// Anfang Attribute
private int kanal;
private int anzahlFunktionen;
protected Bildschirm bildschirm;
protected Audio sound;
// Ende Attribute
// Anfang Konstruktor
public Fernseher(int anzahlFunktionen,
                Bildschirm bildschirm,
                Audio sound) {
 this.anzahlFunktionen = anzahlFunktionen;
 this.bildschirm = bildschirm;
 this.sound = sound;
 this.kanal = 1;
}
//Ende Konstruktor

Das Mo­dell kommt der Wirk­lich­keit recht nahe: Der Kon­struk­tor will einen Bild­schirm und eine Au­dio­sys­tem über­ge­ben. An­ge­nom­men, es soll ein 36-Zoll Am­bi­light-Fern­se­her mit Dol­by­Di­gi­tal-Sound her­ge­stellt wer­den. Dann wer­den zu­nächst die Ob­jek­te am­bi­light­Bild­schir­m1 und dol­by­Di­gi­tal1 er­zeugt. Dann erst wird der Fern­se­her her­ge­stellt, der diese Ob­jek­te als „Bau­tei­le“ be­kommt.

Im UML-Tool kann man den Vor­gang si­mu­lie­ren. Nach dem Druck auf OK steht einem ein kom­plettes Fern­seh-Ob­jekt zur Ver­fü­gung.

Vorgang simulieren im UML-Tool

Me­tho­den, die es selbst hat, wer­den dort aus­ge­führt (z.B. na­echs­ter­Ka­nal), Me­tho­den, die sich auf den Bild­schirm (hel­lig­kei­tEr­ho­ehen) oder das Audio-Sys­tem (laut­sta­er­keEr­ho­ehen) bezie­hen, be­nut­zen die set- bzw. get-Me­tho­den der je­wei­li­gen Ob­jek­te. Das heißt ins­be­son­de­re, dass das Ob­jekt fern­se­her1 vom Ob­jekt dol­by­Di­ti­gal1 ver­langt, mit sei­nen Me­tho­den eine Auf­ga­be zu er­le­di­gen. Ein Code-Aus­schnitt:

public void lautstaerkeErhoehen() {
   sound.setLautstaerke(sound.getLautstaerke()+1);
  }
  public void helligkeitErhoehen() {
   bildschirm.setHelligkeit(bildschirm.getHelligkeit()+1);
  }
  public void naechsterKanal() {
   kanal++;
  }

Hin­weis: Das UML-Tool des Java-Edi­tors er­kennt die Art der Be­zie­hung er­war­tungs­ge­mäß nicht selbst. Von daher wird der pas­sen­de Be­zie­hungs-Pfeil per Kon­text­me­nü hin­zu­ge­fügt.

As­so­zia­ti­on

Die obige Be­zie­hung („hat“) ver­langt, dass das Ob­jekt, mit dem die Be­zie­hung be­steht, Teil des Gan­zen ist. Im Bei­spiel wer­den dem Kon­struk­tor von Fern­se­her als Pa­ra­me­ter zwei Ob­jek­te über­ge­ben, ohne die der Fern­se­her un­voll­stän­dig wäre: Ein Bild­schirm-Ob­jekt und ein Audio-Ob­jekt. Diese Be­zie­hung wurde Ag­gre­ga­ti­on ge­nannt.

Im Prin­zip funk­tio­niert der Fern­se­her schon jetzt, wenn auch etwas un­kom­for­ta­bel: Es fehlt eine Fern­be­die­nung.

Die Fern­be­die­nung „kennt“ einen Fern­se­her. Damit die Un­ter­schei­dung zur Ag­gre­ga­ti­on bes­ser sicht­bar wird, ver­zich­ten wir im Kon­struk­tor der Klas­se Fern­be­die­nung auf die Über­ga­be des Pa­ra­me­ters fern­se­her. Wir spen­die­ren der Fern­be­die­nung dafür eine Me­tho­de ver­bin­dungAuf­neh­men, ohne deren Ak­ti­vie­rung das Fern­seh-Ob­jekt Null (das leere Ob­jekt) ist. Die­ses Vor­ge­hen ent­spricht in der Rea­li­tät der Erst-Co­die­rung der Fern­be­die­nung.

Hier eine Ge­samt­über­sicht und im An­schluss der Code für die Fern­be­die­nung:

Gesamtübersicht

public class Fernbedienung {
   // Anfang Attribute
   private boolean batterieGeladen;
   private Fernseher fernseher;
   // Ende Attribute
   //Anfang Konstruktor
   public Fernbedienung() {
     this.batterieGeladen = true;
 } //Ende Konstruktor
   // Anfang Methoden
   public void tastendruckSenden(int taste) {
     switch (taste) {
       case 0: fernseher.lautstaerkeErhoehen(); break;
       case 1: fernseher.lautstaerkeVermindern(); break;
       case 2: fernseher.helligkeitErhoehen(); break;
       case 3: fernseher.helligekeitVermindern(); break;
       case 4: fernseher.kontrastErhoehen(); break;
       case 5: fernseher.kontrastVermindern(); break;
       case 6: fernseher.naechsterKanal(); break;
 } // end of switch
   }
   public boolean getBatterieGeladen() {
     return batterieGeladen;
   }

   public void verbindungAufnehmen(Fernseher fernseher) {
     this.fernseher = fernseher;
   }
   // Ende Methoden
 } // end of Fernbedienung

Ver­gleicht man beide Be­zie­hun­gen, so wird klar, dass eine Ag­gre­ga­ti­on eine spe­zi­el­le As­so­zia­ti­on ist.

 

 

Ein­füh­rung: Her­un­ter­la­den [odt][330 KB]

 

Wei­ter zu Zu­griffs­mo­di­fi­zie­rer