所謂類的組合是指:類中的成員數據是另一個類的對象或者是另一個類的指針或引用。通過類的組合可以在已有的抽象的基礎上實現更復雜的抽象。 例如:
1、按值組合
#include<iostream.h>
#include<math.h>
class Point
{
public:
Point(int xx,int yy)//構造函數
{
x=xx;
y=yy;
cout<<"Point's constructor was called"<<endl;
}
Point(Point &p);//拷貝構造函數
int GetX(){return x;
int GetY(){return y;}
~Point()
{
cout<<"Point's destructor was called"<<endl;
}
private:
int x,y;
};
Point::Point(Point &p)
{
x=p.x;
y=p.y;
cout<<"Point's copyConstructor was called"<<endl;
}
class Distance
{
private:
Point p1,p2; //按值組合,將類Point的對象聲明爲類Distance的數據成員
double dist;
public:
Distance(Point a,Point b);//包含Point類
double GetDis(void)
{
return dist;
}
~Distance()
{
cout<<"Distance's destructor was called"<<endl;
}
};
Distance::Distance(Point a,Point b):p1(a),p2(b)
{
double x=double(p1.GetX()-p2.GetX());
double y=double(p1.GetY()-p2.GetY());
dist=sqrt(x*x+y*y);
cout<<"Distance's constructor was called"<<endl<<endl;
}
void main()
{
Point myp1(1,1),myp2(4,5);
Distance myd(myp1,myp2);
cout<<'\n'<<"the distance is: "<<myd.GetDis()<<endl<<endl;
}
2、按引用組合
class ZooAnimal
{
public:
// ....
private:
Endangered *_endangered1 ; //按指針組合
Endangered &_endangered2 ; //按引用組合
};
另外再看一個例子:
如果鳥是可以飛的,那麼鴕鳥是鳥麼?鴕鳥如何繼承鳥類?[美國某著名分析軟件公司2005年面試題]
解析:如果所有鳥都能飛,那鴕鳥就不是鳥!回答這種問題時,不要相信自己的直覺!將直覺和合適的繼承聯繫起來還需要一段時間。
根據題幹可以得知:鳥是可以飛的。也就是說,當鳥飛行時,它的高度是大於0的。鴕鳥是鳥類(生物學上)的一種。但它的飛行高度爲0(鴕鳥不能飛)。
不要把可替代性和子集相混淆。即使鴕鳥集是鳥集的一個子集(每個駝鳥集都在鳥集內),但並不意味着鴕鳥的行爲能夠代替鳥的行爲。可替代性與行爲有關,與子集沒有關係。當評價一個潛在的繼承關係時,重要的因素是可替代的行爲,而不是子集。
答案:如果一定要讓鴕鳥來繼承鳥類,可以採取組合的辦法,把鳥類中的可以被鴕鳥繼承的函數挑選出來,這樣鴕鳥就不是“a kind of”鳥了,而是“has some kind of”鳥的屬性而已。代碼如下:
#include<string>
#include<iostream>
using namespace std;
class bird
{
public:
void eat()
{
cout<<"bird is eating"<<endl;
}
void sleep()
{
cout<<"bird is sleeping"<<endl;
}
void fly();
};
class ostrich
{
public:
eat()
{
smallBird.eat();
}
sleep()
{
smallBird.sleep();
}
private:
bird smallBird; //在這裏使用了組合,且是按值組合:將bird的一個對象聲明爲另一類的數據成員
};
int main()
{
ostrich xiaoq;
xiaoq.eat();
xiaoq.sleep();
return 0;
}