Kategorie szkoleń | Egzaminy | Kontakt

Odpowiedź (1)

  • 5

Oba pojęcia różnią się między sobą i pełnią inną rolę.

 

W wyniku DZIEDZICZENIA nowa klasa przejmuje pełne zachowanie klasy bazowej:

// klasa bazowa
public class A {
  public void metoda1() {...};
  public void metoda2() {...};
  public void metoda3() {...};
  // itd.
}

 

// klasa potomna (dziedzicząca)
public class B extends A {
                              // metoda1() i metoda2() są dziedziczone
                              // z klasy A
  public void metoda3() {...} // metoda przedefiniowana
  public void metoda4() {...} // metoda dostępna tylko dla obiektów 
                              // typu B
}



Na obiekcie klasy A można wywołać metody 1-3, na obiekcie klasy B można wywołać metody 1-4 (metody 1-2 zostają przejęte z klasy A, metoda3 ma zmienione zachowanie).

Dzięki polimorfizmowi można do obiektu B odwołać się poprzez referencję typu A (relacja IS_A) i wywołać następujące metody:

 

A ref = new B();
ref.metoda1(); // metoda z klasy A
ref.metoda2(); // metoda z klasy A
ref.metoda3(); // metoda z klasy B - zachowanie polimorficzne

// aby wywołać metodę 4 należy dokonać "rzutowania w dół":
((B)ref).metoda4();

 

 

DELEGACJA jest wzorcem z programowania OO, w którym obiekt zamiast sam wykonać pewną operację deleguje ją (zleca do wykonania) innemu obiektowi pomocniczemu (delegatowi). Następuje tu więc odwrócenie odpowiedzialności. Delegat jest odpowiedzialny za wykonanie zadania obiektu delegującego. Tyle teorii. W praktyce może to wyglądać następująco:

 

public class B {
  private A a; // delegat

  public B(A a) {
    this.a = a;
  }

  public void metoda1() {
    a.metoda1();
    ...
  }

  // itd.
}



Wtedy klasa B może powielić (lub zmienić) tylko wybrane metody klasy A (delegata).

 

To rozwiązanie można jeszcze ulepszyć. W przykładzie powyżej klasy A i B są ze sobą ściśle związane. Tę relację można rozluźnić dzięki użyciu interfejsów:

 

public interface I {
  void metoda1();
  void metoda2();
  void metoda3();
}

 


Ten sam interfejs może implementować wiele klas np.:

 

public class A1 implements I {
  public void metoda1() {...}
  public void metoda2() {...}
  public void metoda3() {...}
}
// inna implementacja interfejsu I
public class A2 implements I {
  public void metoda1() {...}
  public void metoda2() {...}
  public void metoda3() {...}
}

 


Teraz klasa B może wykorzystać delegację nie wiążąc się z żadną konkretną klasą:

 

public class B {
  private I i;

  public B(I i) {
    this.i = i;
  }

  public void metoda1() {
    i.metoda1();
    ...
  }

  // itd.
}

 


Z delegacją możemy się zetknąć w wielu miejscach.

Przykładem może być sortowanie kolekcji. Tworząc metodę sortującą, nie jesteśmy w stanie określić a priori sposobu sortowania. W każdym zastosowaniu porządek może być inny. Co więcej, w jednym programie może chcieć sortować te same dane wg różnych kryteriów. Dlatego do określenia porządku sortowania musimy posłużyć się zewnętrzną klasą, która implementuje określony interfejs.

W API kolekcji metoda sort ma następującą sygnaturę:

 

public static <T> void sort(List<T> list, Comparator<? super T> c)

 


Pierwszy argument jest interfejsem umożliwiającym podanie dowolnej kolekcji typu listy.

Drugi argument jest interfejsem umożliwiającym podanie dowolnej klasy definiującej porządek sortowania (poprzez metodę compare interfejsu Comparator).

 

I jeszcze jedna różnica. W Javie mamy dziedziczenie jednobazowe (klasa może dziedziczyć tylko po jednej klasie). Możemy więc udostępnić metody tylko z jednej klasy-przodka.

W delegacji klasa może posiadać referencje do wielu obiektów i udostępnić metody z wielu klas.

 

 

  • Odpowiedział
  • @ | 29.04.2014
  • TRENER MODERATOR ALTKOM AKADEMII
Komentarze
Przy okazji udało się przemycić wstrzykiwanie zależności (DI) przez konstruktor.
Skomentował : @ mkjasinski ,30.04.2014
  • 9
  • 37
  • 24