Szerkesztő:Vereczkibalint/Öröklődés helyett objektum-összetétel
Az objektum-orientált programozásban (OOP) öröklődés helyett objektum-összetétel (másnéven összetétel újrafelhasználási elv) alapja, hogy az osztályoknak polimorf viselkedést és a kód újrafelhasználást kell megvalósítania a kompozíciójukkal (azáltal, hogy saját példányokat tárolnak más osztályokból, melyek implementálják a kívánt funkcionalitást) ahelyett, hogy egy ősosztályból öröklődnének.
Alapok
[szerkesztés]Az elv implementációja tipikusan azzal keződik, hogy különféle interfészeket készítünk, melyek leírják a viselkedéseket, melyeket a rendszernek tartalmaznia kell. Az interfészek teszik lehetővé a polimorfizmust. Az osztályok implementálják az interfészeket, így öröklődés nélkül megadhatjuk a rendszer egyes részeinek a működési viselkedését.
Példa
[szerkesztés]Öröklődés
[szerkesztés]Egy példa C++11-ben:
#include <vector>
class Model;
class JátékObjektum {
public:
virtual ~JátékObjektum() = default;
virtual void Frissít() {}
virtual void Rajzol() {}
virtual void Ütközés(const std::vector<JátékObjektum*>& objektumok) {}
};
class Látható : public JátékObjektum {
public:
void Frissít() override {
// |model_| rajzolása ezen objektum helyzetére
};
private:
Model* model_;
};
class Test : public JátékObjektum {
public:
void Ütközés(const std::vector<JátékObjektum*>& objektumok) override {
// |objektumok|-al való ütközések ellenőrzése és azokra reagálás
};
};
class Mozgatható : public JátékObjektum {
public:
void Frissít() override {
// Pozíció frissítése.
};
};
Vannak konkrét osztályaink:
Játékos
osztály - amelyTest
,Mozgatható
ésLátható
Felhő
osztály - amelyMozgatható
ésLátható
, de nemTest
Épület
osztály - amelyTest
ésLátható
, de nemMozgatható
Csapda
osztály - amelyTest
, de se nemLátható
, se nemMozgatható
Figyelembe kell venni, hogy az öröklődés veszélyes, ha nincs kellő gondossággal implementálva, ugyanis ez a gyémánt problémához vezethet. Egyik megoldás ennek elkerülésére, hogy ilyen osztályokat készítsünk: LáthatóÉsTest
,LáthatóÉsMozgatható
, LáthatóÉsTestÉsMozgatható
, és mindezt az összes lehetséges kombinációra. Ez viszont rengeteg kódismétléshez vezet. A C++ megoldja a gyémánt problémát azzal, hogy engedi a virtuális öröklődést.
Kompozíció és interfészek
[szerkesztés]A következő C # példa bemutatja a kompozíció és az interfészek használatának elvét, hogy megvalósuljon a kód újrafelhasználás, és a polimorfizmus.
class Program {
static void Main() {
var játékos = new JátékObjektum(new Látható(), new Mozgatható(), new Test());
játékos.Frissít(); játékos.Ütközés(); játékos.Rajzol();
var felhő = new JátékObjektum(new Látható(), new Mozgatható(), new NemTest());
felhő.Frissít(); felhő.Ütközés(); felhő.Rajzol();
var épület = new JátékObjektum(new Látható(), new NemMozgatható(), new Test());
épület.Frissít(); épület.Ütközés(); épület.Rajzol();
var csapda = new JátékObjektum(new Láthatatlan(), new NemMozgatható(), new Test());
csapda.Frissít(); csapda.Ütközés(); csapda.Rajzol();
}
}
interface ILátható {
void Rajzol();
}
class Láthatatlan : ILátható {
public void Rajzol() {
Console.Write("Nem fogok megjelenni.");
}
}
class Látható : ILátható {
public void Rajzol() {
Console.Write("Megjelentem.");
}
}
interface Ütközhető {
void Ütközés();
}
class Test : Ütközhető {
public void Ütközés() {
Console.Write("Bang!");
}
}
class NemTest : Ütközhető {
public void Ütközés() {
Console.Write("Splash!");
}
}
interface Frissíthető {
void Frissít();
}
class Mozgatható : Frissíthető {
public void Frissít() {
Console.Write("Előre megyek.");
}
}
class NemMozgatható : Frissíthető {
public void Frissít() {
Console.Write("Egyhelyben maradok.");
}
}
class JátékObjektum : ILátható, Frissíthető, Ütközhető {
private readonly ILátható _látható;
private readonly Frissíthető _frissíthető;
private readonly Ütközhető _ütközhető;
public JátékObjektum(ILátható látható, Frissíthető frissíthető, Ütközhető ütközhető) {
_látható = látható;
_frissíthető = frissíthető;
_ütközhető = ütközhető;
}
public void Frissít() {
_frissíthető.Frissít();
}
public void Rajzol() {
_látható.Rajzol();
}
public void Ütközés() {
_ütközhető.Ütközés();
}
}
[[Kategória:C sharp kód példák]]
- ↑ Freeman, Eric. Head First Design Patterns. O'Reilly, 23. o. (2004). ISBN 978-0-596-00712-6