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

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).

主站蜘蛛池模板: 天峨县| 东乌珠穆沁旗| 两当县| 资阳市| 昭觉县| 威海市| 东阳市| 青铜峡市| 新津县| 华安县| 搜索| 德州市| 吉林省| 紫云| 大新县| 铁力市| 渝北区| 滁州市| 万荣县| 尉犁县| 博兴县| 泽普县| 浦东新区| 永胜县| 高碑店市| 泸州市| 郧西县| 宜良县| 新竹县| 张北县| 青州市| 兰考县| 衡阳市| 景洪市| 门源| 朔州市| 奈曼旗| 三台县| 重庆市| 澄城县| 宜川县|