Dowiedz się, kiedy klasa powinna dziedziczyć z innej klasy.
Spotkałem sporo uczniów, którzy dopiero zaczynali od programowania obiektowego (OOP) i nie byli zdezorientowani, kiedy klasa powinna dziedziczyć z innej klasy. Celem tego artykułu jest zatem możliwie najjaśniejsze wyjaśnienie tej kwestii.
Kiedy stosować dziedziczenie (relacja jest-a)
Rozważ następujące klasy:
- Zwierzę
- Ssak
- Pies
- Pudel
Na podstawie naszej wiedzy ogólnej wiemy, że:
- Ssak jest zwierzęciem (ale zwierzę może nie być ssakiem)
- Pies to ssak (ale ssak może nie być psem)
- Pudel to pies (ale pies może nie być pudlem)
W tym przypadku relacja is-a przekłada się na dziedziczenie.
- Ssak jest zwierzęciem → Zwierzę jest klasą nadrzędną, a Ssak jest klasą podrzędną → Ssak dziedziczy po Zwierzę
- Pies jestssakiem → Ssak jest klasą nadrzędną, a Pies jest klasą podrzędną → Pies dziedziczy po Ssaku
- Pudel jestpsem → Pies jest klasą nadrzędną, a Pudel jest klasą podrzędną → Pudel dziedziczy po Psie
Przykładowa realizacja
class Animal(): # stuff class Mammal(Animal): # stuff class Dog(Mammal): # stuff class Poodle(Dog): # stuff
Tutaj klasa Mammal
dziedziczy po klasie Animal
, więc klasa Animal
jest umieszczona w nawiasach w definicji klasy Mammal
. To samo dla Dog
i Mammal
oraz Poodle
i Dog
.
Kiedy nie używać dziedziczenia (relacja ma-A)
Relacja ma jest często błędnie interpretowana jako dziedziczenie. Rozważ następujące klasy:
- Firma
- Dział
- Pracownik
Na podstawie naszej wiedzy ogólnej wiemy, że:
- Firma ma wiele działów (ale dział nie jest firmą)
- Dział ma wielu Pracowników (ale Pracownik nie jest Działem)
Tutaj relacja ma nie przekłada się na dziedziczenie. Dział nie powinien dziedziczyć po Firmie, a Pracownik nie powinien dziedziczyć po Departamencie.
Przykładowa realizacja
class Company(): def __init__(self): self.departments = [] class Department(): def __init__(self): self.employees = [] class Employee(): # stuff
Zauważ, że Department
nie dziedziczy po Company
— zamiast tego Company
ma atrybut departments
, który jest listą zawierającą wiele Department
obiektów. Podobnie Employee
nie dziedziczy po Department
. Zamiast tego Department
ma atrybut employees
— listę zawierającą wiele Employee
obiektów.
Więcej przykładów
Kształt i trójkąt
W tym przypadku trójkąt jestkształtem (bardziej szczegółową wersją kształtu), więc wiemy, że klasa Triangle powinna dziedziczyć po klasie Shape.
class Shape(): # stuff class Triangle(Shape): # stuff
Użytkownik i Użytkownik Premium
Tutaj użytkownik premium jestużytkownikiem (bardziej specyficzną wersją użytkownika), więc wiemy, że PremiumUser powinien dziedziczyć po klasie User.
class User(): # stuff class PremiumUser(User): # stuff
Klasa i klasa matematyczna
W tym przypadku klasa odnosi się do zajęć, na które uczniowie chodzą, aby się czegoś nauczyć, a nie do koncepcji programowania. MathClass tutaj jestklasą (bardziej szczegółową wersją Class), więc wiemy, że MathClass powinna dziedziczyć po klasie Class.
class Class(): # stuff class MathClass(Class): # stuff
Klasa matematyczna i uczeń
Wiemy, że na lekcjach matematyki jest wielu uczniów. Obiekt MathClassma wielu Studentów i podobnie obiekt MathClass ma wiele obiektów Studentów. Jednak Student nie jestMathClass, więc nie ma tutaj żadnego dziedziczenia.
class MathClass(): def __init__(self, stuff): self.stuff = stuff self.students = [] # list of Student objects class Student(): # stuff
Rodzic (człowiek) i dziecko (człowiek)
Tutaj klasa Parent odnosi się do ludzkiego rodzica (mama/tata), natomiast klasa Child odnosi się do ludzkiego dziecka. Co dziwne, tutaj nie ma miejsca na dziedziczenie! Ludzkie dziecko nie jestludzkim rodzicem, a Dziecko nie jest bardziej szczegółową wersją Rodzica. W związku z tym klasa Child nie dziedziczy po klasie Parent! (mimo że w prawdziwym życiu dziecko może odziedziczyć rzeczy po rodzicach)
# A long-winded example class Parent(): def __init__(self, name): self.name = name self.children = [] class Child(): def __init__(self, name): self.name = name self.father = None self.mother = None bob = Parent("bob") mary = Parent("mary") tom = Child("tom") jerry = Child("jerry") children = [tom, jerry] bob.children = children mary.children = children tom.father = bob tom.mother = mary jerry.father = bob jerry.mother = mary
Gang i członek gangu
Gang składa się z wielu członków gangu, ale członek gangu nie jest gangiem. Nie ma tu żadnego dziedzictwa.
class Gang(): def __init__(self, stuff): self.stuff = stuff self.members = [] class GangMember(): # stuff
Kilka ostatnich słów
Mam nadzieję, że te przykłady wyjaśnią, kiedy powinniśmy używać dziedziczenia, a kiedy nie — często musimy sprawdzić, czy istnieje związek między naszą rzekomą klasą podrzędną a klasą nadrzędną. Jeśli związek jest-a nie ma sensu:
- Uczeń to klasa matematyczna
- Dziecko jest rodzicem
- Członek gangu to gang
Trzymajmy się z daleka od dziedziczenia.
Wniosek
Jeśli ten artykuł był wartościowy i chcesz wesprzeć mnie jako pisarza, rozważ zapisanie się do członkostwa Medium — kosztuje 5 USD miesięcznie i masz nieograniczony dostęp do historii na Medium. Jeśli zarejestrujesz się za pomocą mojego linku poniżej, otrzymam niewielką prowizję bez dodatkowych kosztów.
Zarejestruj się, korzystając z mojego linku, aby czytać nieograniczoną liczbę artykułów na Medium!
Jeśli ten artykuł był dla Ciebie niezwykle wartościowy, rozważ kupno mi kawy — każda drobna wpłata będzie dla Ciebie niezwykle cenna!
https://www.buymeacoffee.com/zlliu
Jeśli chcesz otrzymywać powiadomienia o każdej mojej publikacji, rozważ dołączenie do mojej listy e-mailowej.
Więcej treści na plainenglish.io. Zapisz się na nasz „bezpłatny cotygodniowy biuletyn”. Uzyskaj wyłączny dostęp do możliwości pisania i porad w naszym Discord społeczności.