2010-09-15 10 views
8

Co to jest klasa abstrakcyjna i interfejs w PHP i kiedy z nich skorzystasz? Odpowiedź laików na przykładzie byłaby wspaniała, by pomóc mi zrozumieć.Co to jest KLASA ABSTRAKCJI i INTERFEJS i kiedy używałbyś ich w PHP?

+0

mógłbyś przejść odpowiedzi do tego i poprzednich pytań i zaakceptować najbardziej przydatne z nich lub edytować swoje pytania podkreślić, dlaczego żadna z odpowiedzi rozwiązać swoje pytanie. Dzięki. – Gordon

Odpowiedz

7

Klasy abstrakcyjne i interfejsy nie są specyficzne dla PHP; są cechami wielu współczesnych języków obiektowych.

Klasa abstrakcyjna to klasa, która ma jedną lub więcej niezatwierdzonych funkcji składowych. Możesz użyć jednego w sytuacji, w której chcesz zestaw klas, które mają podobne zachowania, różniące się tylko w kilku metodach. Każda z tych klas wywodzi się z klasy abstrakcyjnej i implementuje niezimplementowane metody w sposób odpowiedni dla ich konkretnego przypadku.

Interfejs jest podobny do klasy abstrakcyjnej, ale nie zawiera żadnych implementacji metod, tylko podpisy. Klasa implementująca interfejs musi implementować wszystkie metody.

Klasa może implementować wiele interfejsów, ale może pochodzić tylko z jednej klasy abstrakcyjnej (lub klasy macierzystej dowolnego rodzaju), ponieważ PHP nie obsługuje dziedziczenia wielokrotnego.

Obie abstrakcyjne klasy i interfejsy pozwalają na polimorfizm; tj. można określić odwołanie do typu abstrakcyjnego (które może odnosić się do dowolnego wystąpienia klasy pochodnej od niego) lub do obiektu implementującego interfejs.

+0

Doskonała odpowiedź. Czy istnieją różnice między byciem rodzicem a byciem klasą abstrakcyjną? –

+1

@Travis: Tak. Klasa abstrakcyjna nie może być utworzona. Od czasu do czasu tworzę klasy abstrakcyjne, aby dzielić niekompletną funkcjonalność (zakładając, że relacja rodzic-pod jest naprawdę relacją 'is-a'). Po utworzeniu podklasy dostępna jest pełna funkcjonalność klasy/instancji. –

+0

dobre wyjaśnienie. Mam coś do dodania ... W PHP i Javie metody interfejsu muszą być publiczne. – Alex

0

Interfejs definiuje zestaw metod, które musi implementować klasa. Taka klasa implementuje interfejs, zapewniając konkretną implementację tych metod. Interfejs nie może zawierać żadnej własnej implementacji; to tylko zestaw sygnatur metod. Jeśli zdefiniuję interfejs o nazwie ILogger, to mogę napisać kod, który używa metod zdefiniowanych w ILogger (może write i writeLine) do przekazywania wiadomości, które mają być rejestrowane. Mogę przekazać dowolną klasę, która implementuje ILogger, a to wszystko jest takie samo dla kodu klienta.

Klasa abstrakcyjna jest podobna, ale może implementować niektóre metody i stan. Klasa abstrakcyjna nie może być utworzona w instancji, a każda klasa, która je rozszerza, musi zapewnić implementację każdej metody abstract w klasie nadrzędnej. Jeśli zestaw klas zawiera pewne szczegóły implementacji, ale różnią się one w innych, można zdefiniować wspólną implementację w klasie abstrakcyjnej, zadeklarować różne metody abstrakcyjne i pozwolić klasom podrzędnym wypełnić je własną implementacją. Jeśli chciałbym uzyskać jednolity sposób zbierania informacji o systemie, dodawać sygnatury czasowe itp., Które są wspólne dla wszystkich moich rejestratorów, mogę utworzyć abstrakcyjną klasę LoggerBase, która obsługuje te szczegóły, oznaczając write i writeLineabstract, tak aby wszystkie klasy rozszerzające LoggerBase były wystarczy określić sposób zapisywania w swoim dzienniku.

4

Zakładając, że rozumiesz, dlaczego używasz ich w innych językach, te same pojęcia odnoszą się do PHP. Interfejsy są "sygnaturami" klasowymi ... nie zawierają kodu. Klasy abstrakcyjne nie mogą być tworzone, ale mogą zawierać zarówno funkcje zaimplementowane, jak i abstrakcyjne (puste).

Należy pamiętać, że klasa może rozszerzać tylko jedną klasę nadrzędną (lub klasę abstrakcyjną), ale może implementować tyle interfejsów, ile potrzebuje.

Biorąc pod uwagę, że PHP nie ma ścisłego wpisywania i nie ma pojęcia o sprawdzaniu czasu kompilacji, użytkownik może zazwyczaj wykonywać je bez nich, w przeciwieństwie do języków takich jak C++ lub Java.

Podstawowy PHP wymaga interfejsów dla niektórych rzeczy. Na przykład:

class Foo implements Countable 
{ 
    public function count() 
    { 
    return 5; 
    } 
} 

echo count(new Foo()); // returns 5 

Jeśli usunąć „realizuje policzalny” PHP nie wywołać metodę count. Istnieje wiele innych interfejsów, które można zaimplementować, aby umożliwić niestandardowym obiektom zachowanie się w podobny sposób. Na przykład można utworzyć obiekt, który działa z iteracją foreach.

Interfejsy na poziomie użytkownika nie są niezwykle przydatne w PHP, jak już wcześniej wspomniałem. Jeśli jednak skorzystać z podpowiedzi typu, mogą być:

function foo(MyInterface $bar) 
{ 
    $bar->someMethod(); 
} 

Zakładając someMethod jest zadeklarowana w MyInterface, wtedy masz gwarancję, że wezwanie do $bar->someMethod() istnieje. (Powodem, dla którego nie jest to tak użyteczne w PHP, jak w innych językach, jest fakt, że wskazówka dotycząca typu w sygnaturze funkcji nie zostanie sprawdzona do czasu wykonania).

Puste interfejsy mogą być również przydatne jako sposoby kategoryzuj klasy. Powiedzmy, że chcesz coś zrobić z konkretnym zestawem obiektów. Mogli wszyscy wdrożyć jakiś pusty interfejs. Wtedy twój kod mógłby po prostu sprawdzić ten interfejs, nie wiedząc nic o obiekcie.

interface Red {} 

class Foo implements Red { } 

$foo = new Foo(); 
if ($foo instanceof Red) 
{ 
    // do something 
} 

Klasy abstrakcyjne są użyteczne, gdy masz dużo kodu, który jest wspólny dla podklas, ale sam nie jest znaczący. Możesz zadeklarować klasę podstawową jako abstrakcyjną, zaimplementować wszystkie udostępnione funkcje i pozostawić pozostałe funkcje puste. Deklarując tę ​​klasę podstawową jako abstrakcyjną, nikt nigdy nie będzie w stanie jej używać samodzielnie.

Powiązane problemy