原书抄录:
一个C++类有着两个重要的方面:用于描述类行为的公有接口,以及行为的私有实现。
大多数继承所采用的都是公有继承的形式:派生类同时继承了基类的借口和实现。
在私有基类中,派生类继承了所有的实现,但没有继承任何接口。
而在继承公有的抽象基类时,派生类继承了所有的接口,但所继承的实现可能是不完整的或者是不存在的。
规则总结:
- 我们要找出简单的抽象
- 我们要识别出对实现的继承;可以使用私有基类或者(更好的方法是)使用成员对象
- 我们应该考虑使用默认参数的形式来代替函数重载的形式。
章后习题:
解答:
我创建一个基类Point,两个派生类Circle和Line。
其中, Circle通过私有继承的方式获取Point的服务, 而因为要使用两个point对象,因此Line私有成员的方式获取服务。
代码:
#include <iostream>
#include <cmath>
using namespace std;
class Point
{
public:
Point(int x_, int y_):
x(x_), y(y_)
{}
void SetLoc(int x_, int y_)
{
x = x_, y = y_;
}
int GetX() const
{
return x;
}
int GetY() const
{
return y;
}
private:
int x, y;
};
class Circle: private Point
{
public:
Circle(int x_, int y_, int r_):
Point(x_, y_), r(r_)
{}
void Set(int x_, int y_, int r_)
{
Point::SetLoc(x_, y_);
r = r_;
}
void SetLoc(int x_, int y_)
{
Point::SetLoc(x_, y_);
}
void SetRadius(int r_)
{
r = r_;
}
Point GetLoc() const
{
return Point(Point::GetX(), Point::GetY());
}
int GetRadius() const
{
return r;
}
double Area() const
{
return 3.14*r*r;
}
double Length() const
{
return 2 * 3.14 * r;
}
private:
int r;
};
class Line
{
public:
Line(int x1, int y1, int x2, int y2):
sp(x1, y1), ep(x2, y2)
{}
void SetLoc(int x1, int y1, int x2, int y2)
{
sp.SetLoc(x1, y1);
ep.SetLoc(x2, y2);
}
void SetStart(int x, int y)
{
sp.SetLoc(x, y);
}
void SetEnd(int x, int y)
{
ep.SetLoc(x, y);
}
Point GetStart() const
{
return sp;
}
Point GetEnd() const
{
return ep;
}
double Length() const
{
return sqrt( pow(sp.GetX() - ep.GetX(), 2) + pow(sp.GetY() - ep.GetY(), 2) );
}
private:
Point sp, ep;
};
int main()
{
Circle c(0, 0, 1);
Point p = c.GetLoc();
cout << "Circle Loc: (" << p.GetX() << ", " << p.GetY() << ")" << endl;
cout << "Circle Area: " << c.Area() << endl;
cout << "Circle Length: " << c.Length() << endl;
Line l(-1, 2, 3, 5);
Point sp = l.GetStart(), ep = l.GetEnd();
cout << "Line Start Loc: (" << sp.GetX() << ", " << sp.GetY() << ")" << endl;
cout << "Line End Loc: (" << ep.GetX() << ", " << ep.GetY() << ")" << endl;
cout << "Line Length: " << l.Length() << endl;
return 0;
}