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

Inheritance

Inheritance is a programming concept that allows us to reuse classes. Programming languages provide different implementations of inheritance, but the general rule always stands: the class relationship should answer the is-a question. For example, a Car is-a Vehicle, which allows us to inherit the Car from the Vehicle:

class Vehicle {
public:
void move();
};

class Car : public Vehicle {
public:
Car();
// ...
};

The Car now has the move() member function derived from the Vehicle. Inheritance itself represents a generalization/specialization relationship, where the parent class (Vehicle) is the generalization and the child class (Car) is the specialization.

The parent class could be referred to as the base class or the superclass, while the child class could be referred to as the derived class or the subclass, respectively. 

You should only consider using inheritance if it is absolutely necessary. As we mentioned earlier, classes should satisfy the is-a relationship, and sometimes, this is a bit tricky. Consider the Square and Rectangle classes. The following code declares the Rectangle class in its simplest possible form:

class Rectangle {
public:
// argument checks omitted for brevity
void set_width(int w) { width_ = w; }
void set_height(int h) { height_ = h; }
int area() const { return width_ * height_; }
private:
int width_;
int height_;
};

The Square is-a Rectangle, so we could easily inherit it from the Rectangle:

class Square : public Rectangle {
public:
void set_side(int side) {
set_width(side);
set_height(side);
}

int area() {
area_ = Rectangle::area();
return area_;
}

private:
int area_;
};

The Square extends the Rectangle by adding a new data member, area_, and overwriting the area() member function with its own implementation. In practice, the area_ and the way we calculate its value are redundant; we did this to demonstrate a bad class design and to make the Square extend its parent to some extent. Soon, we will conclude that the inheritance, in this case, is a bad design choice. Square is a Rectangle, so it should be used as a Rectangle wherever the Rectangle is used, as shown here:

void make_big_rectangle(Rectangle& ref) {
ref->set_width(870);
ref->set_height(940);
}

int main() {
Rectangle rect;
make_big_rectangle(rect);
Square sq;
// Square is a Rectangle
make_big_rectangle(sq);
}

The make_big_rectangle() function takes a reference to the Rectangle and the Square inherits it, so it's totally fine to send a Square object to the make_big_rectangle() function; the Square is-a a Rectangle. This example of the successful substitution of a type with its subtype is known as the Liskov Substitution Principle. Let's find out why this substitution works in practice and then decide if we made a design mistake by inheriting the Square from the Rectangle (yes, we did).

主站蜘蛛池模板: 连州市| 永年县| 合江县| 乌苏市| 湟源县| 甘泉县| 南郑县| 吐鲁番市| 社会| 锡林郭勒盟| 博罗县| 抚州市| 庆元县| 莫力| 兴安县| 枣阳市| 新营市| 苍溪县| 梨树县| 建瓯市| 天气| 石狮市| 稻城县| 山阴县| 修文县| 英超| 岱山县| 余庆县| 深泽县| 修武县| 东莞市| 阿瓦提县| 平遥县| 铜山县| 廉江市| 嘉兴市| 峨眉山市| 天气| 武宁县| 庆元县| 德兴市|