Ugrás a tartalomhoz

Is-a

Ellenőrzött
A Wikipédiából, a szabad enciklopédiából

A tudásreprezentációban, objektumorientált programozásban és tervezésben (lásd objektumorientált program architektúra ), az-egy (is_a vagy az-egy) egy absztrakciók közötti alárendelt kapcsolat (pl típusok, osztályok ), ahol az egyik osztály, A, egy másik osztály, B, alosztálya (és így B superclass-a az A-nak). Más szavakkal, az A típus a B típus altípusa, amikor A specifikációja magában foglalja B specifikációját. Vagyis bármely olyan objektum (vagy osztály), amely megfelel az A specifikációjának, szintén megfelel a B specifikációnak, mert B specifikációja gyengébb.[1]

Az az-egy kapcsolat ellentétben áll a van-egy ( has_a vagy a ) kapcsolattal a típusok (osztályok) között; összekeverni a van-egy és az-egy kapcsolatokat gyakori hiba, amikor modellt szerkesztünk (pl számítógépes program ) az objektum és az alárendelt valós kapcsolatáról. Az az-egy viszony ellentétben állhat az objektumok (példányok) és a típusok (osztályok) közötti instance-of kapcsolattal is: lásd " típus-token megkülönböztetés " és " típus-token kapcsolatok ".[2]

Összegezve a kapcsolatokat, van

  • hiperonim - hyponym ( szupertípus – altípus) kapcsolatok a típusok (osztályok) között, meghatározva egy taxonómiai hierarchiát, ahol
    • szubupupciós viszony esetén: a hiponím (altípus, alosztály) type-of ( az-egy ) összefüggésben van hiperonimájával (szupertípus, szuperosztály);
  • holonym - meronym (teljes / entitás / konténer-rész / alkotóelem / tag) típusok (osztályok) közötti kapcsolatok, amelyek egy birtokló hierarchiát határoznak meg, ahol
    • összesítő (vagyis tulajdonjog nélküli) kapcsolat esetén:
      • egy (teljes) holonymnak van-egy kapcsolata van a meronimával (részleges),
    • összetétel (azaz tulajdonosi) kapcsolat esetén:
      • egy meronima (alkotóelem) part-of kapcsolata vana a holonimjával (entitásával),
    • az elszigetelés [3] kapcsolatához:
      • egy meronym (tag) van egy member-of kapcsolata van a holonimjával ( konténer );
  • concept-object (típus-token) kapcsolat van a típusok (osztályok) és az objektumok (példányok) között, ha
    • egy tokennek (objektumnak) egy instance-of kapcsolata van a típusával (osztályával).

Példák az altípusokra

[szerkesztés]

A subtyping lehetővé teszi, hogy egy adott típust váltson egy másik típus vagy absztrakció. A subtyping létrehoz egy az-egy kapcsolatot az altípus és néhány meglévő absztrakció között, vagy explicit vagy implicit módon,nyelvi támogatástól függően.A kapcsolatot ki lehet fejezni örökléssel, azon nyelvek esetén, amik támogatják azt, mint subtyping mechanism.

Az alábbi C ++ kód létrehoz egy kifejezett öröklés kapcsolatot a B és A osztályok között, amelyben B jelentése egyaránt egy alosztálya, és egy altípusa A-nak, és fel lehet használni, mint egy A-t, ahol egy B van megadva (egy referenciával, egy mutatóval vagy objectként ).

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.
}

[4]

Python

[szerkesztés]

A következő python kódot hoz létre explicit öröklés közötti kapcsolat osztályok B és A B ahol egyszerre alosztály és altípusa A és fel lehet használni, mint egy A ahol a B van szükség.

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.

A következő példa szerint a type(a) "normál", és az type(type(a)) egy metatípus. Míg eloszlatva az összes típusnak azonos metatípusa van ( PyType_Type, amely szintén a saját metatípusa), ez nem követelmény. A klasszikus osztályok típusa, az úgynevezett types. ClassType különálló metatípusnak is tekinthető.[5]

>>> 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-ban az az-egy kapcsolat egy osztály vagy interfész típusparamétereinek és egy másik típusparamétereinek kapcsolatát a kiterjesztések és az implementációs záradékok határozzák meg.

A Gyűjtemény osztályok használatával az ArrayList <E> megvalósítja az List<E>-t , és az <E> Lista kiterjeszti a Collection<E>-t . Tehát az ArrayList <String> a <String> lista altípusa, amely a Collection<String> altípusa. Az altípus-kapcsolat automatikusan megmarad a típusok között. Amikor meghatározunk egy interfészt, a PayloadList-t, amely egyesíti a P típusú általános opcionális értéket az egyes elemekkel, akkor annak deklarálása a következőképpen nézhet ki:

interface PayloadList<E, P> extends List<E> {
    void setPayload(int index, P val);
    ...
}

A PayloadList következő paraméterei a List<String> altípusai:

PayloadList<String, String>
PayloadList<String, Integer>
PayloadList<String, Exception>

Liskov-helyettesítési elv

[szerkesztés]

A Liskov-helyettesítési elv magyarázatot ad egy tulajdonságra: "Ha minden S típusú o1 objektumhoz van egy T típusú o2 objektum, oly módon, hogy a T-vel definiált valamennyi P programnál P viselkedése nem változik, ha o1 helyett o2 van, akkor S "a T altípusa" .[6] A következő példa az LSP megsértését mutatja.

void DrawShape(const Shape& s)
{
  if (typeid(s) == typeid(Square))
    DrawSquare(static_cast<Square&>(s));
  else if (typeid(s) == typeid(Circle))
    DrawCircle(static_cast<Circle&>(s));
}

Nyilvánvaló, hogy a DrawShape funkció rosszul formázva van. A Shape osztály minden derivatív osztályáról tudnia kell. Ezenkívül meg kell változtatni, amikor a Shape új alosztálya jön létre. Objektumorientált tervezésben ezt a struktúrát tekintjük anatémának. Íme egy finomabb példa az LSP megsértésére:

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; }
  private:
    double itsWidth;
    double itsHeight;
};

Ez jól működik, de a négyzet osztálynál, amely a Téglalap osztályt örököli, megsérti az LSP-t, annak ellenére, hogy fennáll az az-egy kapcsolat a Téglalap és a Négyzet között. Mert a négyzet téglalap alakú. A következő példa felülírja a probléma megoldásához két funkciót, a Setwidth és a SetHeight funkciókat. A kód javítása azonban azt jelenti, hogy a tervezés hibás.

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);
}

A következő példa szerint a g függvény csak a téglalap osztályra működik, de a négyzetre nem, és így megsértették a nyitott-zárt alapelvet.

void g(Rectangle& r)
{
  r.SetWidth(5);
  r.SetHeight(4);
  assert(r.GetWidth() * r.GetHeight()) == 20);
}

Kapcsolódó szócikkek

[szerkesztés]

Megjegyzések

[szerkesztés]
  1. Subtypes and Subclasses. MIT OCW. (Hozzáférés: 2012. október 2.)
  2. Type–token relations
  3. See also Containment (computer programming).
  4. Mitchell, John. 10 "Concepts in object-oriented languages", Concepts in programming language. Cambridge, UK: Cambridge University Press, 287. o. (2002). ISBN 0-521-78098-5 
  5. Guido van Rossum: Subtyping Built-in Types. (Hozzáférés: 2012. október 2.)
  6. Liskov, Barbara. Data Abstraction and Hierarchy. SIGPLAN Notices (1988. május 1.) 

Irodalom

[szerkesztés]