Wzorce projektowe

Dziedziczenie - uwagi

(na podstawie: www.p-programowanie.pl )

Dziedziczenie według dr. Konrada Grzanka nie powinno być nadużywane, gdyż powoduje to problemy projektowe: pojedyncza zmiana powoduje całą serię następujących po sobie zmian w modułach zależnych. Związek dwóch klas nie powinien być zbyt silny.

Związki te opisuje Diagramy klas UML

  • Asocjacja jest związkiem pomiędzy dwoma klasami. Jest silniejszym wiązaniem niż zależność. Paradoksalnie w odróżnieniu od zależności, w asocjacji dwie klasy nie wpływają na siebie. Oznacza to, że usunięcie jednego obiektu nie wpływa w żadnym stopniu na drugi.
  • Agregacja częściowa jest mocniejszą odmianą zwykłej asocjacji. Jeżeli spotkasz się z nazwą samej agregacji, oznacza to że chodzi o agregację częściową. Jest to związek dwóch klas w formie relacji całość-część. Ważnym jest fakt, że usunięcie klasy całość nie wpływa na istnienie klasy część.

Dziedziczenie umożliwia wyodrębnienie cech wspólnych dla kilku klas i zamknięciu ich w klasie bardziej ogólnej – o wyższym poziomie abstrakcji. Klasy dziedziczące po klasie bazowej przejmują jej cechy. Pozwala to znacznie skrócić kod i zorganizować kod od strony logicznej.

Realizacja własnej listy z wykorzystaniem typów generycznych

(autor wersji pierwotnej kodu: Konrad Grzanek, podczas zajęć na SAN)

interface Seq<T>

public interface Seq<T> {
   T first();
   Seq<T> rest();
   Seq<T> cons(T obj);
   boolean isEmpty();
}

class Nil<T> implements Seq<T>

public class Nil<T> implements Seq<T> {
   public static <S> Seq<S> nil() {
     return new Nil<S>();
   }
   @Override
   public T first() {
     return null;
   }
   @Override
   public Seq<T> rest() {
     return this;
   }
   @Override
   public Seq<T> cons(T obj) {
     return new LinkedSeq<>(obj, this);
   }
   @Override
   public boolean isEmpty() {
     return true;
   }
}

class LinkedSeq<T> implements Seq<T>

public class LinkedSeq<T> implements Seq<T> {
   public static <S> Seq<S> of(S... elements) {
     Seq<S> result = Nil.nil();
     for (int i = elements.length - 1; i >= 0; i--) {
	result.cons(elements[i]);
	System.out.print(elements[i] + " ");
     }
     System.out.println();
     return result;	
   }
   private final T first;
   private final Seq<T> rest;
   public LinkedSeq(T first, Seq<T> rest) {
     this.first = first;
     this.rest = rest;
   }
   @Override
   public T first() {
     return this.first;
   }
   @Override
   public Seq<T> rest() {
     return this.rest;
   }
   @Override
   public Seq<T> cons(T obj) {
     return new LinkedSeq<>(obj, rest);
   }
   @Override
   public boolean isEmpty() {
     return false;
   }
}

class Test

public class Test {
   public static void main(String[] args) {
      Seq<String> s1 = LinkedSeq.of("Kamil", "Adam", "Monika");
      System.out.println(s1.isEmpty());
      Seq<Double> s2 = LinkedSeq.of(Math.PI, Math.E, Math.abs(-99.9));
      System.out.println(s2.isEmpty());
   }
}