In the previous article we covered a basic concept of object-oriented-encapsulation, encapsulation is a relatively simple concept, but also very easy to accept, but many occasions below, just encapsulation does not solve a lot of problems, consider the following example:
Let's say we need to design a battle detail against the game and in the initial version we will support an action--fight. Suppose we have three roles: Fighter, knight, and Warrior, each of which has a different health and hit point, and based on the basic idea of encapsulation, we naturally think of the encapsulation of the class for each object, with the first obvious 2 elements: health, hit Point, there are also name (we can not only three characters) and the speed of combat speed, methods are: Hit, IsAlive. Based on this idea, we give the following class:
class fighter
{
private:
int m_iHealth;
int m_iSpeed;//为了方便,这个值使用延时值,越大表示速度越慢
const int m_iHitPoint;
char m_strName[260];
public:
fighter(const char* strName);
void hit(fighter* pfighter);
bool isAlive();
};
The above class can clearly abstract out one of the data types we need to express, and here you may have found some problems:
The member function hit is used to deal with combat events, but we have different roles, fighter cannot fight with just the same opponents, we want it to fight any character, and of course, using template functions can solve this problem simply. In addition, we have to implement three different classes, and these classes must all implement these properties and methods. Even though we've solved all these problems, now we want to organize two teams to fight, we want to use a group type to describe them, the problem is that we have to set the corresponding group structure for each species, of course, you can think of 3 different types are not many, can be fully dealt with, then if the system upgrades, When you need to manage hundreds of types of time, will it be a big head?
In C + +, inheritance can be a good solution to this problem, in C + +, inheritance represents a is-a relationship, that is, derived classes Is-a base class, many real-world relationships can be described, such as: Dog Is-a Animal,dog is the derivation of animal (inheritance), Inherited objects have all the properties and behaviors of the parent (base) object, such as all the properties and behavior of the animal in dog. In the UML description, this relationship is called generalization (generalization). Under normal circumstances, using inheritance is a good solution when we need to implement a series of similarities (with certain commonalities) but have different categories, such as the previous code, although it can also achieve our goals, but it is obviously difficult to manage, the following is the implementation of using inheritance:
Class actor//base class
{
Protected
int m_ihealth;
const int m_ispeed;//For convenience, this value uses a delay value, the greater the speed the slower
const int M_ihitpoint;
Char m_strname[260];
Public
Actor (const char* strname,const int ihealth,const int ispeed,const int ihitpoint);
int& Health () {return m_ihealth;};
Const char* GetName () {return m_strname;};
virtual void hit (actor *actor) = 0;
BOOL IsAlive ();
};
Actor::actor (const char* strname,const int ihealth,const int ispeed,const int ihitpoint):
M_ihealth (Ihealth),
M_ispeed (Ispeed),
M_ihitpoint (Ihitpoint)
{
strcpy (M_strname,strname);
}
BOOL Actor::isalive ()
{
return (m_ihealth>0);
}
/////////////////////////////////////////////////////////
Class fighter
Class fighter:p Ublic actor
{
Public
Fighter (const char* strName);
virtual void hit (actor *actor);
Private
};
Fighter::fighter (const char* strName):
Actor (strname,100,20,20)
{
}
void Fighter::hit (actor *actor)
{
Sleep (m_ispeed);
if (!isalive ())
{
return;
}
if (Actor&&actor->isalive ())
{
Here we use a function to do the left value, because the function returns a reference
if (IsAlive ())
Actor->health () = Actor->health ()-m_ihitpoint;
}
}
/////////////////////////////////////////////////////////
Class Knight
Class Knight:p ublic actor
{
Public
Knight (const char* strName);
virtual void hit (actor *actor);
Private
};
Knight::knight (const char* strName):
Actor (strname,150,20,25)
{
}
void Knight::hit (actor *actor)
{
Sleep (m_ispeed);
if (!isalive ())
{
return;
}
if (Actor&&actor->isalive ())
{
if (IsAlive ())
Actor->health () = Actor->health ()-m_ihitpoint;
}
}
/////////////////////////////////////////////////////////
Class Warrior
Class Warrior:p ublic actor
{
Public
Warrior (const char* strName);
virtual void hit (actor *actor);
Private
};
Warrior::warrior (const char* strName):
Actor (strname,150,20,25)
{
}
void Warrior::hit (actor *actor)
{
Sleep (m_ispeed);
if (!isalive ())
{
return;
}
if (Actor&&actor->isalive ())
{
if (IsAlive ())
Actor->health () = Actor->health ()-m_ihitpoint;
}
}