Kiedy wdrożyć i rozszerzyć? [Zamknięte]

90
  • Kiedy należy implementlub extendnależy używać?
  • Jakie są przykłady z prawdziwego świata?

Czy to jest poprawne?

Wydaje się, że implementacja jest sposobem na wymuszenie istnienia pewnych metod w klasie i prawidłowego sformatowania wywołań funkcji tych metod. Implementacja nie jest jednak sposobem przekazywania zmiennych lub „ustawień” do klasy?

Oczekiwany scenariusz z życia: Mam platformę handlu elektronicznego zawierającą wiele klas płatności, które mają ten sam projekt. Kiedy należy dodać nową klasę płatności, bardzo łatwo jest zastosować się do zdefiniowanego projektu, interfaceaby upewnić się, że wszystkie bity i elementy są dostępne od początku.

Rozszerzanie klas powoduje, że klasa rozszerzona (potomna?) Dziedziczy wszystko z klasy nadrzędnej z wyjątkiem metod i zmiennych zadeklarowanych jako private?

Oczekiwany scenariusz z życia wzięty: wywołałem jedną klasę sessionsz dwiema klasami podrzędnymi o nazwach sessioncookiesi databasesessions. sessioncookiesi databasesessionsrazem dziedziczą szereg wzajemnych opcji konfiguracyjnych z sesji nadrzędnych, ułatwiając zmianę opcji konfiguracji, aby wpływać na wszelkiego rodzaju ostateczne przechowywanie danych odwiedzających.

Przemysłowy
źródło
1
Polecam zapoznać się z dziedziczeniem.
Rafe Kettler

Odpowiedzi:

64

Dziedziczenie jest przydatne, aby zmniejszyć ilość przepisywanego kodu. Jeśli masz kilka klas z kilkoma typowymi metodami lub polami, zamiast nieustannie definiować te metody i pola, możesz uwzględnić je w klasie bazowej i sprawić, by każda z klas potomnych rozszerzała tę klasę bazową.

Interfejsy (i implements) są przydatne, gdy chcesz zdefiniować wspólny protokół jak powinna zachowywać się grupa obiektów. Na przykład możesz chcieć nakazać, aby obiekty, które są porównywalne, można było porównywać pod kątem równości i haszowania itp.

Ostatecznie korzystanie z dziedziczenia jest wyborem projektu. Szukaj przypadków, w których definiujesz te same metody w kilku klasach; są to doskonałe przypadki, w których można podzielić te metody na klasę bazową. To samo dotyczy klas, które mają niektóre z tych samych cech: możesz zagwarantować spójność, umieszczając te cechy w interfejsie, który ma być implementowany przez te powiązane klasy.

Dziedziczenie to wielka koncepcja w OOP, która wykracza poza samo PHP. Polecam przeczytanie artykułu na Wikipedii o dziedziczeniu i być może wzorcach projektowych Gang of Four .

Uważam, że twoje rozumienie dziedziczenia jest głównie poprawne. Następnym krokiem byłoby użycie go w produkcji.

Rafe Kettler
źródło
4
Wiele osób uważa, że ​​książka Gang of Four jest zbyt ciężka pod względem materiału jako wprowadzenie do wzorców projektowych. Popularną alternatywą jest Head First: Design Patterns, która ułatwia czytanie. amazon.co.uk/Head-First-Design-Patterns-Freeman/dp/0596007124
Bendihossan
1
„Szukaj przypadków, w których definiujesz te same metody w kilku klasach; są to doskonałe przypadki, w których możesz rozłożyć te metody na klasę bazową”. Czy rozszerzenie klasy miałoby przewagę nad używaniem cechy do zdefiniowania tych metod?
Daniel Weiner
1
„Dziedziczenie jest przydatne, aby zmniejszyć ilość przepisywanego kodu” - Celem dziedziczenia jest współdzielenie zachowania, a nie kodu. Tam, gdzie to możliwe, cechy są sposobem na udostępnianie kodu, a nie rozszerzanie klasy abstrakcyjnej o konkretne klasy, które w przeciwnym razie nie mają ze sobą nic wspólnego. Zwykle możesz modelować swoje klasy jako relacje typu has-a, a nie jest-a, co dodatkowo ułatwi zarówno ponowne użycie kodu, jak i polimorfizm.
Duncan
12

Wprowadzić w życie:

Interfejsy są klasami abstrakcyjnymi, więc możesz tylko deklarować rzeczy. Klasa implementuje interfejs. Możesz zaimplementować wiele interfejsów.

Poszerzać:

Ci przedłużyć klas gdy chcesz więcej wersji konkretnego z klasą.

Przykład:

// Contract: a pet should play
public interface Pet {
    public void play(); 
}

// An animal eats and sleeps
class Animal {
    public void eat();
    public void sleep();
}


public class Camel extends Animal {

}

public class Dog extends Animal implements Pet {    
    public void play() {...}
}

Zarówno Camel, jak i Dog są zwierzętami, więc poszerzają Animalklasę. Ale tylko psa jest rodzajem specyficznego of Animalktóra również może byćPet

Ahmad Mobaraki
źródło