Jak to różne sposoby na implementacje interfejsu? To nie ma jednego właściwego sposobu na to? Bierzesz takiego, inspirujesz się nim, mówisz że będziesz jak on, spełniasz się, a potem robisz psikusa – jak, po co?
Niby wiesz że interfejs można implementować jawnie i niejawnie. Ale czy wiesz co z tego wynika? Czy wiesz co można z tym zrobić? Różne rzeczy, albo też nic.
Wersja youtube jest na dole.
Zacznijmy od samego interfejsu:
Prosty interfejs definiujący w jakiś sposób osobę, imię, nazwisko i dla oficjeli imię i nazwisko. Nic skomplikowanego.
Implementacja interfejsu:
Wszystko jak najbardziej standardowo. Jest kontrakt, jest implementacja, jest obsługa. Jest cacy.
Różni ludzie, różne zachowania, różna implementacja:
Zaczyna się. Na początku mówię, że właściwości są, ale tylko dlatego że spełniam kontrakt i tylko przez ten kontrakt będę je udostępniać. Jak developer kompilatorowi, tak kompilator developerowi. Aby w takiej sytuacji uzyskać dostęp do właściwości w konstruktorze będę musiał się rzutować na taki kontrakt. Podobnie w metodzie dla oficjeli, aby uzyskać dostęp do właściwości robię rzut.
Różnica w zapisie deklaracji metody Fullname a właściwości, powoduje to, że metoda jest dostępna w dla instancji ClosedPerson, podczas gdy Firstname oraz Lastname są dostępne tylko przez dostęp kontraktowy. Pacz na obrazek:
Zrób coś bardziej szalonego:
W tym momencie zwiększyłem poziom szaleństwa z poprzedniego przykładu i teraz klasa TrickyPerson w zależności od tego w jaki sposób (w zależności od typu) się do niej odwołamy będzie zachowywać się lekko inaczej. Łat?
Ale to nic, bo klimat zabawy można podkręcić jeszcze troszkę dalej:
Dołożyłem kolejny interfejs, który ponownie definiuje metodę Fullname, a potem klasa która w zależności od tego jak się na nią spojrzy będzie zachowywać się inaczej.
To wszystko w połączone w jedność:
Co spowoduje taki output na ekranie:
Co dalej?
Na plus, jeśli nie korzystasz z abstrakcji, możesz ukryć część implementacji przed innymi programistami, np. publiczne setery i wymusić, aby wszystko zostało podane przez konstruktor.
Możesz wymusić korzystanie z abstrakcji, poprzez np. rzucanie wyjątków gdy ktoś odwołuje się do konkretnej implementacji klasy a nie kontraktu.
Możesz korzystać z rozszerzonego logowania gdy korzystasz z konkretnej klasy.
Ale ponad wszystko pamiętaj aby nie robić czegoś zupełnie, zupełnie innego niż mówi metoda, czy czegoś czego nie spodziewa się użytkownik twojej klasy. Chciałem napisać o zasadzie Baśki (SOLID), ale w ciężko mi tutaj się do niej odwołać, bo tutaj jest implementacja interfejsu a nie zupełniej innej klasy. Ale warto mieć to w głowie.
Nagranie do wpisu:
Chyba gdzieś >>nie<< zjadło w tym zdaniu
Ale ponad wszystko pamiętaj aby robić czegoś zupełnie, zupełnie innego niż mówi metoda, czy czegoś czego nie spodziewa się użytkownik twojej klasy.
Podziękował i poprawił 🙂
To że można coś zrobić, nie znaczy że powinno się. Haki są spoko (np. wykorzystywanie mało znany mechanizmów języka) dopóki są eleganckie i czytelne dla obiorców 😉
Ale na pewno takie eksperymenty są odkrywcze i pouczające.
Jasna sprawa, trochę jak z bronią palną. To że trzymasz ją w ręku nie znaczy, że masz strzelać do wszystkich w zasięgu widzenia 🙂
Jak na razie dopiero wchodzę w to wszystko, więc dla mnie czarna magia, ale dodaję bloga do ulubionych i do zakładek. Czekam na kolejne wpisy 🙂
Dzięki. Będą. Ogarniam prezentację na najbliższe wystąpienie.