Je speciálním případem
![ikona](http://upload.wikimedia.org/wikipedia/commons/thumb/6/6a/Under_construction_icon-orange.svg/48px-Under_construction_icon-orange.svg.png)
{{Pracuje se}}
, abyste zabránili editačním konfliktům.![](http://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Preferences-system.svg/16px-Preferences-system.svg.png)
Je speciálním případem, je druhem, je typem, anglicky is-a je v ontologii a reprezentaci znalostí[pozn. 1], v objektově orientovaném programování a objektově orientované analýze a návrhu je subsumpční[pozn. 2] vztah mezi abstrakcemi (například, typy, třídami), kdy jedna třída A je podtřídou jiné třídy B (a tedy B je nadtřídou třídy A). Jinými slovy typ A je podtypem typu B, jestliže specifikace A implikuje specifikaci B. Tj. libovolný předmět (nebo třída), který vyhovuje specifikaci A, vyhovuje také specifikaci B, protože specifikace B je slabší.[1]
Například kočka je speciálním případem zvířete, ale ne naopak. Všechny kočky jsou zvířata, ale ne všechna zvířata jsou kočky. Chování, které je relevantní pro všechna zvířata, je definováno na třídě zvířat, zatímco chování, které je relevantní pouze pro kočky, je definováno na třídě koček. Definováním třídy koček jako specializace třídy zvířat všechny kočky zdědí chování definované pro zvířata, aniž by bylo nutné toto chování pro kočky explicitně uvádět.
Příbuzné koncepty
Vztah je speciálním případem (is-a je třeba rozlišovat od vztahu mít něco (has a mezi typy (třídami); zaměňování těchto dvou vztahů je častou chybou při navrhování modelu (například počítačového programu) skutečného vztahu mezi objektem a jeho podřízeným. Vztah je speciálním případem se také liší od vztahu je instancí mezi objekty (instancemi) a typy (třídami): viz Rozlišování typu a entity.
Shrneme-li vztahy, pak jsou to:
- hyperonymum–hyponymum (nadtyp/nadtřída–podtyp/podtřída) relace mezi typy (třídy) definování taxonomic hierarchie, kde
- pro subsumption relace: hyponymum (podtyp, podtřída) je ve vztahu je speciálním případem (is-a) se svým hyperonymem (nadtypem, nadtřídou);
- holonymum–meronymum (celek/entity/kontejner–část/konstituent/člen) vztahy mezi typy (třídami) definujícími hierarchii vlastnění, kde
- pro relaci agregace (tj. bez vlastnictví):
- holonymum (celý) je ve vztahu má se svým meronymem (částí),
- pro skládání (tj. s vlastnictví) relace:
- meronymum (konstituent) je ve vztahu je částí se ho holonymem (entity),
- pro containment[2] relace:
- meronymum (člen) je ve vztahu je členem se svým holonymem (kontejnerem);
- pro relaci agregace (tj. bez vlastnictví):
- koncept–předmět (typ–token) relace mezi typy (třídami) a objekty (instancemi), kde
- token (předmět) je ve vztahu je instancí se svým typem (třídou).
Příklady podtypování
Podtypování umožňuje nahradit jeden typ jiným typem nebo abstrakci. Říkáme, že podtypování vytváří vztah je speciálním případem mezi podtypem a nějakou existující abstrakcí, a to buď implicitně anebo explicitně, v závislosti na podpoře jazyka. V jazycích podporujích dědičnost jako mechanismus podtypování lze tento vztah vyjádřit explicitně prostřednictvím dědičnosti.
C++
Následující kód v jazyce C++ vytváří explicitní vztah dědičnosti mezi třídami B a A, kde B je jak podtřídou i tak podtypem třídy A, a může být použita jako třída A všude tam, kde je uvedena třída B (prostřednictvím reference, ukazatele nebo samotného objektu).
class A { public: void DoSomethingALike() const {} }; class B : public A { public: void DoSomethingBLike() const {} }; void UseAnA(A const& some_A) { some_A.DoSomethingALike(); } void SomeFunc() { B b; UseAnA(b); // b can be substituted for an A. }
[3]
Python
Následující kód v jazyce Python vytváří explicitní vztah dědičnosti mezi třídami B and A, kde B je jak podtřídou i tak podtypem třídy A, a může být použita jako třída A všude tam, kde je vyžadována třída B.
class A: def do_something_a_like(self): pass class B(A): def do_something_b_like(self): pass def use_an_a(some_a): some_a.do_something_a_like() def some_func(): b = B() use_an_a(b) # b can be substituted for an A.
V následujícím příkladě je type(a) „běžný“ typ a type(type(a)) je metatyp. Ačkoli všechny typy, tak jak jsou distribuované, mají stejný metatyp PyType_Type, který je zároveň vlastním metatypem), není to podmínkou. Typ klasických tříd, známý jako types.ClassType, lze také považovat za samostatný metatyp.[4]
>>> a = 0 >>> type(a) <type 'int'> >>> type(type(a)) <type 'type'> >>> type(type(type(a))) <type 'type'> >>> type(type(type(type(a)))) <type 'type'>
Java
V jazyce Java se vztah je speciálním případem mezi typovými parametry jedné třídy nebo rozhraní a typovými parametry jiné třídy určuje pomocí klauzulí extends a implements.
Pomocí tříd Collections
implementuje ArrayList<E>
třídu List<E>
, a List<E>
rozšiřuje Collection<E>
. ArrayList<String>
je tedy podtypem typu List<String>
, který je podtypem typu Collection<String>
. Vztah podtypování se mezi typy zachovává automaticky. Při definici rozhraní PayloadList
, které ke každému prvku přiřazuje volitelnou hodnotu generického typu, může jeho deklarace vypadat takto:
interface PayloadList<E, P> extends List<E> { void setPayload(int index, P val); ... }
Následující parameterizace typu PayloadList jsou podtypy typu List<String>
:
PayloadList<String, String> PayloadList<String, Integer> PayloadList<String, Exception>
Liskovové princip zastoupení
Liskovové princip zastoupení (LSP) vysvětluje vlastnost „Jestliže pro každý objekt o1 typu S existuje objekt o2 typu T takový, že pro všechny programy P definované v termínech T se chování P nezmění, když je o1 nahrazeno o2, pak S je podtypem T“,[5]
Následující příklad ukazuje narušení Liskovové principu zastoupení.
class Rectangle { public: void SetWidth(double w) { itsWidth = w; } void SetHeight(double h) { itsHeight = h; } double GetHeight() const { return itsHeight; } double GetWidth() const { return itsWidth; } double GetArea() const { return GetHeight() * GetWidth(); } private: double itsWidth; double itsHeight; };
Z programátorského hlediska lze třídu Square implementovat děděním z třídy Rectangle.
public class Square : Rectangle { public: virtual void SetWidth(double w); virtual void SetHeight(double h); }; void Square::SetWidth(double w) { Rectangle::SetWidth(w); Rectangle::SetHeight(w); } void Square::SetHeight(double h) { Rectangle::SetHeight(h); Rectangle::SetWidth(h); }
To však porušuje LSP, přestože mezi obdélníkem Rectangle a čtverecem Square platí vztah je speciálním příkadem.
Uvažujme následující příklad, kde funkce g nefunguje, pokud je předán Čtverec, a tak by se dalo uvažovat o porušení principu otevřeného-uzavřeného.
void g(Rectangle& r) { r.SetWidth(5); r.SetHeight(4); assert(r.GetArea()) == 20); // assertion will fail }
Opačně, pokud uvažujeme, že typ tvaru by měl být pouze omezením na vztah jeho rozměrů, pak předpoklad v g(), že SetHeight změní výšku a plochu, ale ne šířku, který je neplatný, ne pouze pro skutečné čtverce, ale dokonce potenciálně i pro jiné obdélníky, které by mohly být kódovány tak, aby při změnách výšky zachovávaly plochu nebo poměr stran.
[6]
Odkazy
Poznámky
Reference
V tomto článku byl použit překlad textu z článku is-a na anglické Wikipedii.
- ↑ Subtypes and Subclasses [online]. MIT OCW [cit. 2012-10-02]. Dostupné online.
- ↑ Viz též objektová kompozice.
- ↑ MITCHELL, John. Concepts in programming language. Cambridge, UK: Cambridge University Press, 2002. ISBN 0-521-78098-5. Kapitola 10 "Concepts in object-oriented languages", s. 287. Je zde použita šablona
{{Cite book}}
označená jako k „pouze dočasnému použití“. - ↑ Guido van Rossum. Subtyping Built-in Types [online]. [cit. 2012-10-02]. Dostupné online. Je zde použita šablona
{{Cite web}}
označená jako k „pouze dočasnému použití“. - ↑ LISKOV, Barbara. Data Abstraction and Hierarchy. [s.l.]: SIGPLAN Notices, May 1988. Dostupné v archivu pořízeném z originálu dne 2020-06-21.
- ↑ The Liskov Substitution Principle [online]. Robert C. Martin, 1996 [cit. 2012-10-02]. Dostupné v archivu pořízeném dne 2015-09-05.
Literatura
- BRACHMAN, Ronald J., 1983. What IS-A is and isn't. An Analysis of Taxonomic Links in Semantic Networks. IEEE Computer. Říjen 1983, roč. 16, čís. 10. Dostupné online.
- HAINAUT, Jean-Luc; HICK, Jean-Marc; ENGLEBERT, Vincent; HENRARD, Jean; ROLAND, Didier, 1996. Understanding Implementations of IS-A Relations]. ER 1996: 42-57. [s.l.]: [s.n.]. S. 42–57.
Související články
- Dědičnost (objektově orientované programování)
- Liskovové princip zastoupení (v objektově orientovaném programování)
- Subsumpce
- Hypernymum (a supertyp)
- Hyponymum (a podtyp)
- Vztah má
- Holonymie
- Meronymie