官术网_书友最值得收藏!

Why inheritance hierarchies are inflexible

The idea that Players, Enemies, Missiles, and Medics should all derive from one base object is very common to programmers new to object-oriented programming. It makes a lot of sense on paper that if you have a Raider and a SuperRaider, one should inherit from the other. I believe this comes from how inheritance is taught. When you are first learning about inheritance, you will almost always see a picture similar to this:

Figure 3.1 - A typical inheritance diagram when learning to program

Many introductory programming courses are so focused on the mechanics of inheritance that they forget to tell you how to use it properly. A picture like the one above makes it easy to understand that ITWorker is an Employee, which is a Person. However, once you go beyond the mechanics, it is time to learn how to use inheritance correctly. This is why books on design patterns exist.

Inheritance is a powerful tool that lets us extend classes by adding members and methods that are specific to the derived classes. It allows us to start with general code and create more specialized classes. This solves one of the original problems that we had with the extremely bloated object struct in the first section. Inheritance lets us take an existing class, such as a Raider, and add more members to create a SuperRaider:

//Inheritance Based Object: 
class Object
{
public:
Object(void);
virtual ~Object(void);//virtual destructor is important
virtual void Update(float dt);
virtual void CollisionReaction(Object* pCollidedWith);
protected:
//We still need the basic data in all object
M5Vec2 m_pos;
M5Vec2 m_scale;
float m_rotation;
int m_textureID;
};

//Inheritance Based derived class
class Unit: public Object
{
public:
Unit(void);
virtual ~Unit(void);
virtual void Update(float dt);
virtual void CollisionReaction(Object* pCollidedWith);
protected:
M5Vec2 m_vel;//So that Units can move
float m_maxSpeed;
float m_health;
float m_damage;
};

class Enemy: public Unit
{
public:
Enemy(void);
virtual ~Enemy(void);
virtual void Update(float dt);
virtual void CollisionReaction(Object* pCollidedWith);
protected:
unsigned char m_color[4];
float m_textureCoords[4];//For animation
};

Figure 3.2 - An example of Space Shooter inheritance hierarchy

This hierarchy makes a lot of sense when first designing a space shooter. It allows us to separate the details of a Raider class or a Bomber class away from the Player class. Adding a game object is easy because we can extend a class to create what we need. Removing a game object is easy because all the code is contained within each derived class. In fact, now that we have separate classes, each one can be responsible for itself via class methods. This means we no longer need switch statements all over our code.

Best of all, we can use the power of virtual functions to decouple our derived classes from the core engines of our game. By using an array of base class pointers to the derived class instances, our core engines such as graphics or physics are only coupled to the object interface instead of derived classes, such as Planet or SpawnerStation.

Without inheritance hierarchy, the code would be as follows:

//Create our objects 
Object gameObjects[MAX_COUNT];

//initialization code here
//...

for(int i = 0; i < objectsInUse; ++i)
{
switch(gameObjects[i].type)
{
case OT_PLAYER:
//Update based on input
break;
case OT_PLANET:
//Add intercept code here
break;
case OT_ENEMY_SPAWNER:
//Add case code here
break;
case OT_RAIDER:
//Add find target and chase code here
break;
case OT_BOMBER:
//Move slowly and do large damage code here
break;
default:
M5DEBUG_ASSERT(true, "Incorrect Object Type");
}
}

With inheritance and polymorphism, the code is as follows:

//Create our objects 
Object* gameObjects[MAX_COUNT];//array of pointers

//initialization code here
//...

for(int i = 0; i < objectsInUse; ++i)
gameObjects[i]->Update(dt);
主站蜘蛛池模板: 博野县| 吉隆县| 军事| 黑水县| 馆陶县| 海阳市| 四会市| 黎平县| 耿马| 双柏县| 肃北| 滦平县| 房山区| 包头市| 泰宁县| 兴和县| 尚义县| 府谷县| 都江堰市| 富顺县| 高清| 邵武市| 交城县| 疏勒县| 乌拉特中旗| 东光县| 社旗县| 望都县| 色达县| 垦利县| 河池市| 海城市| 延安市| 黎城县| 高州市| 芒康县| 延吉市| 玛多县| 石门县| 安吉县| 河南省|