Hello everyone, I recently got interested (again) in the concept of abstract classes and interfaces. I'm currently designing a simple game using SDL and I decided to use these concepts. So for now I got 3 major interfaces: Renderable, Controllable and Collidable; and a few implementations (like Character, Wall, Zone, etc.). I want to unite them both under a common abstract class GameObject.
The problem is I don't want the GameObject class to support all the interfaces I mentioned above, because this means that every class which extends the common class have to implement all the functions from all the interfaces. Thus, for example, the Wall class, which is a derived class of GameObject, have to implement the Controllable interface without being controllable.
I want the objects to receive functionality from the interfaces they inherit, but and the same time I want them to be accessible only via the common interface GameObject.
Or said in other words:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
class Renderable
{
public:
virtual ~Renderable();
virtual void render(SDL_Surface *) = 0;
// some other pure virtual functions
};
class Controllable
{
public:
virtual ~Controllable();
virtual void move(const int newX, const int newY) = 0;
// some other pure virtual functions
};
class GameObject
{
public:
virtual bool isRenderable() = 0;
virtual bool isControllable() = 0;
// some other functions
protected:
// some common variables
}
class Wall : public GameObject, public Renderable
{
public:
Wall(/* args */);
~Wall();
bool isRenderable();
bool isControllable();
void render(SDL_Surface *);
// more functions
};
class Character : public GameObject, public Renderable, public Controllable
{
public:
Character(/* args */);
~Character();
bool isRenderable();
bool isControllable();
void render(SDL_Surface *);
void move(const int newX, const int newY);
// more functions
};
//---------------------
int main()
{
GameObject *object[100];
object[0] = new Character(/* args */);
object[1] = new Wall(/* args */);
// etc.
// So GameObject has no render() or move() functions
// but both Character and Wall have render() functions
// and Character has move() function
// How can I use this kind of code?
if( object[0]->isRenderable() )
object[0]->render(/*some SDL surface*/);
if( object[1]->isMovable() )
object[1]->move(/*new coords*/);
}
|
I don't wanna use type cast like:
1 2 3 4 5
|
if( object[0]->isRenderable() )
{
Renderable * renderableObject = (Renderable *) object[0];
renderableObject->render(/* ... */);
}
|
because it's risky and it almost never works.
Also, as I stated above, I don't wanna have all the functions from all the interfaces declared in GameObject and implemented in *every* derived class, because half of the implementations would be empty functions which do nothing.
I hope you understood me. I'm still a bit confused about the whole thing.