CodeGym /Blog Java /Random-PL /Domyślne metody w interfejsach
Autor
Volodymyr Portianko
Java Engineer at Playtika

Domyślne metody w interfejsach

Opublikowano w grupie Random-PL
Każda nowa wersja Javy różni się od poprzednich. Oto przykład zmian w materiale, który omówiliśmy: przed Javą 5 język nie miał enums. Domyślne metody w interfejsach - 1Podobnie, Java 8 znacznie różni się od Java 7. Większość naszych lekcji została napisana dla 7. wersji języka, ale oczywiście nie będziemy ignorować ważnych innowacji. Ponieważ w tej lekcji omawialiśmy już interfejsy, rozważymy jedną aktualizację — domyślne metody w interfejsach . Wiesz już, że interfejs nie implementuje zachowania . Jego zadaniem jest opisanie zachowania, jakie muszą posiadać wszystkie obiekty, które go implementują. Jednak programiści często spotykali się z sytuacjami, w których implementacja metody jest taka sama we wszystkich klasach. Rozważmy przykład naszego starego samochodu:

public interface Car {

   public void gas();

   public void brake();
}
public class Sedan implements Car {

   @Override
   public void gas() {
       System.out.println("Gas!");
   }

   @Override
   public void brake() {
       System.out.println("Brake!");
   }
}


public class Truck implements Car {

   @Override
   public void gas() {
       System.out.println("Gas!");
   }

   @Override
   public void brake() {
       System.out.println("Brake!");
   }
}


public class F1Car implements Car {
   @Override
   public void gas() {
       System.out.println("Gas!");
   }

   @Override
   public void brake() {
       System.out.println("Brake!");
   }
}
"Jaki Twoim zdaniem jest główny problem z tym kodem? Pewnie zauważyłeś, że napisaliśmy kilka powtarzających się kodów! Ten problem jest powszechny w programowaniu i musisz go unikać. To inna sprawa, że ​​określone rozwiązania wcześniej nie istniały Została wydana Java 8. Wraz z tą wersją pojawiła się możliwość określania domyślnych metod i implementowania ich bezpośrednio w interfejsie! Oto jak to zrobić:

public interface Car {

   public default void gas() {
       System.out.println("Gas!");
   }

   public default void brake() {
       System.out.println("Brake!");
   }
}

public class Sedan implements Car {

}

public class Truck implements Car {

}

public class F1Car implements Car {

}
Teraz metody gas()i brake(), które były takie same dla wszystkich samochodów, zostały przeniesione do interfejsu. Nie jest potrzebny żaden powtarzający się kod. Co więcej, metody są dostępne na każdych zajęciach!

public class Main {

   public static void main(String[] args) {

       F1Car f1Car = new F1Car();
       Sedan sedan = new Sedan();
       Truck truck = new Truck();
       truck.gas();
       sedan.gas();
       f1Car.brake();
   }
}
Co jeśli istnieje 100 klas z tą gas()metodą, ale tylko 99 z nich zachowuje się tak samo? Czy to wszystko psuje i sprawia, że ​​domyślna metoda nie nadaje się do tej sytuacji? Oczywiście, że nie :) Domyślne metody w interfejsach można nadpisywać w taki sam sposób, jak zwykłe.

public class UnusualCar implements Car {
   @Override
   public void gas() {
       System.out.println("This car accelerates differently!");
   }

   @Override
   public void brake() {
       System.out.println("This car decelerates differently!");
   }
}
Wszystkie 99 innych typów samochodów zaimplementuje metodę domyślną, aUnusualCarclass, która jest wyjątkiem, nie psuje ogólnego obrazu i spokojnie definiuje własne zachowanie. Wielokrotne dziedziczenie interfejsów. Jak już wiesz, Java nie obsługuje wielokrotnego dziedziczenia. Istnieje wiele powodów. Przyjrzymy się im szczegółowo w osobnej lekcji. Inne języki, takie jak C++, obsługują to. Bez wielokrotnego dziedziczenia pojawia się poważny problem: jeden obiekt może mieć kilka różnych cech i „zachowań”. Oto przykład z życia: jesteśmy dziećmi dla naszych rodziców, uczniami dla naszych nauczycieli i pacjentami dla naszych lekarzy. W życiu przyjmujemy różne role iw związku z tym inaczej się zachowujemy: oczywiście nie rozmawialibyśmy z nauczycielami tak, jak rozmawiamy z naszymi bliskimi przyjaciółmi. Spróbujmy przełożyć to na kod. Wyobraź sobie, że mamy dwie klasy: Staw i Woliera. Do stawu potrzebujemy ptactwa wodnego; do woliery potrzebujemy latających ptaków. W tym celu stworzyliśmy dwie klasy bazowe:FlyingBirdi Waterfowl.

public class Waterfowl {
}

public class FlyingBird {
}
W związku z tym wyślemy ptaki, których klasy dziedziczą FlyingBirddo woliery, a ptaki, które dziedziczą, wyślemy Waterfowldo stawu. Wszystko wydaje się bardzo proste. Ale gdzie wysłać kaczkę? Pływa i lata. I nie mamy wielokrotnego dziedziczenia. Na szczęście Java obsługuje wiele implementacji interfejsów. Chociaż klasa nie może dziedziczyć kilku rodziców, może z łatwością zaimplementować kilka interfejsów! Nasza kaczka może być zarówno latającym ptakiem, jak i ptactwem wodnym :) Aby osiągnąć zamierzony efekt, musimy po prostu stworzyć FlyingBirdi interfejsy, a nie klasy.Waterfowl

public class Duck implements FlyingBird, Waterfowl {

   // The methods of both interfaces can be easily combined into one class

   @Override
   public void fly() {
       System.out.println("Fly!");
   }

   @Override
   public void swim() {

       System.out.println("Swim!");
   }
}
W związku z tym nasz program zachowuje elastyczność klas, aw połączeniu z metodami domyślnymi nasze możliwości definiowania zachowania obiektów stają się niemal nieograniczone! :)
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION