📅  最后修改于: 2023-12-03 15:13:45.300000             🧑  作者: Mango
继承是面向对象编程中的一种重要的概念,它允许我们通过定义一个新的类来继承现有的类的属性和方法。这就允许我们使用面向对象编程的核心原则,即 DRY(不要重复自己 - Don't Repeat Yourself)。
在 C++ 中,一个类可以通过以下方式继承另一个类的属性和方法:
class BaseClass {
public:
int x;
};
class DerivedClass : public BaseClass {
public:
int y;
};
在上面的例子中,DerivedClass
继承了 BaseClass
中定义的变量 x
。这意味着我们可以在 DerivedClass
中访问 x
,就像访问 DerivedClass
自己定义的变量 y
一样。
C++ 中有几种不同的继承类型:
DerivedClass
的用户访问 BaseClass
中的公共成员。例如,在上面的示例中,我们可以这样使用:DerivedClass myObj;
myObj.x = 15;
myObj.y = 20;
DerivedClass
访问 BaseClass
中的私有成员,但是它们对 DerivedClass
的用户是不可见的。例如:class BaseClass {
private:
int x;
};
class DerivedClass : private BaseClass {
public:
void setX(int value) {
x = value; // 允许 DerivedClass 访问 x
}
};
在上述示例中,DerivedClass
访问 BaseClass
的私有成员 x
,但它们被 DerivedClass
的用户隐藏起来了。
DerivedClass
访问 BaseClass
中的保护成员。保护成员与私有成员类似,但它们对继承的公共成员是可见的。例如:class BaseClass {
protected:
int x;
};
class DerivedClass : protected BaseClass {
public:
void setX(int value) {
x = value; // 允许 DerivedClass 访问 x
}
};
int main() {
DerivedClass myObj;
myObj.setX(15); // OK,因为 setX 是 DerivedClass 的公共成员
myObj.x = 20; // 错误,因为 x 是 BaseClass 的保护成员
return 0;
}
C++ 继承还允许我们用新的实现覆盖(或重载)从基类继承的方法。例如:
class BaseClass {
public:
void myFunction() {
cout << "Hello from BaseClass" << endl;
}
};
class DerivedClass : public BaseClass {
public:
void myFunction() {
cout << "Hello from DerivedClass" << endl;
}
};
int main() {
BaseClass obj1;
DerivedClass obj2;
obj1.myFunction(); // 输出 "Hello from BaseClass"
obj2.myFunction(); // 输出 "Hello from DerivedClass"
return 0;
}
在上面的例子中,我们定义了两个类 BaseClass
和 DerivedClass
,DerivedClass
继承自 BaseClass
。 BaseClass
定义了一个名为 myFunction
的方法, DerivedClass
中覆盖了该方法并提供了新的实现。此时,obj1
和 obj2
分别位于基类和派生类中,它们都有一个名为 myFunction
的方法,但是在调用时,每个对象将调用自己类中的该方法。这就是多态性的概念,C++ 中的多态性是通过继承实现的。
通常情况下,我们不会创建只继承而不添加新功能的类,因为这没有任何意义。相反,我们使用继承来扩展我们的类并实现新的功能。但是,有时我们需要在不添加新功能的情况下创建一个类,这个类被称为抽象类(或抽象基类)。
抽象类只是一个定义了纯虚函数的类,纯虚函数是一种函数,没有实现,只是一个“占位符”,需要在继承的派生类中实现。例如:
class AbstractClass {
public:
virtual void myFunction() = 0; // 纯虚函数
};
class DerivedClass : public AbstractClass {
public:
void myFunction() {
cout << "Hello from DerivedClass" << endl;
}
};
int main() {
// AbstractClass obj; // 错误,因为抽象类不能被实例化
DerivedClass obj;
obj.myFunction(); // 输出 "Hello from DerivedClass"
return 0;
}
抽象类可以像普通类一样继承,并可以包含数据成员和其他成员函数,但是当我们尝试实例化一个抽象类时,将引发错误。该类的目的是作为其他类的基类,只定义接口而不实现。
到目前为止,我们已经介绍了 C++ 中继承的基础知识,包括不同类型的继承、访问控制、重载函数和多态,以及抽象基类。通过使用继承,我们可以创建一个具有共同特征的类层次结构,可以减少代码重复,并增加灵活性和可扩展性。