Java #27: implementacja interfejsu

Implementacja interfejsu w programowaniu

Pewnie już znasz pojęcie interfejs, które często występuje jako interfejs graficzny. Wtedy można go rozumieć, jako sposób w jakim użytkownik komunikuje się z komputerem (z reguły są to różnego rodzaju buttony, linki, combo boxy, itp.). Interfejs (czy też po angielsku: interface) o którym dziś mowa, jest sposobem w jaki jedna klasa powinna komunikować się z drugą. Dzieje się tak dlatego, bo implementacja interfejsu dokonywana jest właśnie w klasie.

Często w podręcznikach mówi się o „kontrakcie” pomiędzy dwoma stronami usług. Wiem, że brzmi to enigmatycznie. W praktyce chodzi po prostu o to, że przygotowujemy sobie coś, co przypomina bardzo klasę czysto abstrakcyjną (czy zawierającą tylko sygnatury metod *). Każda następna klasa, tak jak w przypadku dziedziczenia po klasie abstrakcyjnej, musi zaimplementować wszystkich jej sygnatur.

Po co taka sztuczka? Pamiętasz lekcję o klasa abstrakcyjnych? Musisz wiedzieć, że programowanie w dzisiejszych czasach to sport zespołowy. Dawno już minęły czasy, gdy kod w całości jest pisany przez jednego programistę. Faktycznie wtedy, gdy piszesz kod sam, mógłbyś nie używać żadnych klas abstrakcyjnych czy interfejsów. Jednak ich używanie, ułatwia kolejnym osobom czytelność kodu i Twoje zamierzenia. Wytłumacz to sobie w ten sposób, że interfejsy wskazują kolejnym osobom, co powinny zaimplementować w klasie. No dobrze, ale skoro są klasy abstrakcyjne, to po co te interfejsy, skoro można używać dziedziczenia? Tu również odpowiedź jest dość zaskakująca, otóż interfejsów możesz implementować nieskończoną ilość, a dziedziczyć (jak już wiesz) można tylko po jednej klasie (lub, co ciekawe, po jednym interfejsie).

Implementacja własnych interfejsów

Dla ćwiczenia stwórz sobie dwa interfejsy. Jeden dla bramkarza a drugi dla każdego innego zawodnika.

public interface GoalKeeperBehaviour {
  public int handle();
}
public interface Skillable {
  public int pass();
  public int attack();
  public int defend();
}

Teraz zaimplementuję zachowanie ogólnie (Skillable) dla napastnika (Striker) oraz dla bramkarza (Goalkeeper), a dodatkowo także zachowanie dla bramkarza (GoalkeeperBehaviour). Gdy tylko wpiszesz w swoich nowo utworzonych klasach interfejs, Eclipse na czerwono zaznaczy Ci, że należy zaimplementować wszystkie metody, których sygnatury są w interfejsie.

public class GoalKeeper implements GoalKeeperBehaviour, Skillable {
  // blad, brak zaimplementowanych wymaganych metod
}

Poprawne przykładowa implementacja interfejsu, mogą wyglądać tak:

public class Striker implements Skillable {

  @Override
  public int pass() {
    return 15;
  }

  @Override
  public int attack() {
    return 17;
  }

  @Override
  public int defend() {
    return 9;
  }
}

Możesz też implementować więcej niż jeden interfejs

public class GoalKeeper implements GoalKeeperBehaviour, Skillable {

  @Override
  public int pass() {
    return 8;
  }

  @Override
  public int attack() {
    return 4;
  }

  @Override
  public int defend() {
    return 6;
  }

  @Override
  public int handle() {
    return 18;
  }
}

Możesz też rozszerzyć jeden interfejs o drugi:

public interface CaptainBehaviour {
  public int makeInfluance();
}
public interface Skillable extends CaptainBehaviour, GoalKeeperBehaviour{
  public int pass();
  public int attack();
  public int defend();
}

Co więcej możesz tu rozszerzać (w przeciwieństwie do klas) o więcej niż jeden interfejs.

public class PlayerMain {
  public static void main(String[] args) {
    GoalKeeper goalKeeper = new GoalKeeper();
    System.out.println(goalKeeper.handle());
    Skillable striker = new Striker();
    System.out.println(striker.attack());
  }
}

Teraz możesz wywołać stworzone klasy w metodzie main. Zauważ, że od tej lekcji możesz tworzyć obiekty nie tylko poprzez użycie nazwy klasy w sekcji deklaratywnej (po lewej stronie znaku „równa się”), ale także z użyciem interfejsu (np. Skillable striker = new Striker();). Używanie interfejsów pozwala na bardziej elastyczne pisanie kodu, ale docenisz to dopiero z czasem.

Podsumujmy informacje o interfejsach:

  • zawierają dowolną liczbę sygnatur metod (czyli metodę bez jej ciała)
  • są widoczne w pakietach tak jak klasy
  • nie możesz stworzyć instancji interfejsu (czyli np. Skillable skills = new Skillable(); nie zadziała, podobnie jak w przypadku klasy abstrakcyjnej)
  • mogą zawierać stałe (public static final..)
  • nie posiadają zmiennych klasowych i konstruktorów
  • implementacja interfejsu dokonywana jest w klasie.
  • klasy nie mogą być rozszerzane przez interfejsy (ani na odwrót)
  • interfejs może być rozszerzone o inne interfejsy
  • od Javy 8 doszły nowe zmiany dotyczące interfejsów, które opowiem Ci w oddzielnym kursie, w którym skupię się tylko na zmianach jakie zaszły w tej wersji Javy

Link do lekcji: https://github.com/developeronthego/java-middle/tree/master/src/main/java/middle/lesson10

Powtórka o tym, czy jest polimorfizm: Java #19: polimorfizm i słowo kluczowe this

Stay in the Loop

Get the daily email from CryptoNews that makes reading the news actually enjoyable. Join our mailing list to stay in the loop to stay informed, for free.

Ostatnio dodane

- Advertisement - spot_img

Powiązane wpisy