一、public继承的定义
public继承是C++中最常见的继承方式之一。它的定义方式如下:
class DerivedClass : public BaseClass { ... };
这样定义后,DerivedClass就会从BaseClass中继承所有public成员,而BaseClass中的protected和private成员则不能被DerivedClass访问。
二、public继承的实现方式
public继承的实现方式是通过在DerivedClass类中包含一个BaseClass对象来实现的:
class BaseClass { public: ... }; class DerivedClass : public BaseClass { public: ... private: BaseClass m_base; };
这里m_base是DerivedClass类中的成员变量,它是由BaseClass类实例化而来的,因此DerivedClass类就可以访问BaseClass中的所有public成员。
三、public继承的用途
1. 代码复用
public继承最常见的用途就是为了代码复用。如果DerivedClass需要重用BaseClass中的代码(公共接口),那么可以通过public继承来实现。
例如:
class Shape { public: virtual int GetArea() = 0; virtual int GetPerimeter() = 0; }; class Rectangle : public Shape { public: Rectangle(int width, int height) : m_width(width), m_height(height) {} int GetArea() override { return m_width * m_height; } int GetPerimeter() override { return 2 * (m_width + m_height); } private: int m_width, m_height; }; class Square : public Rectangle { public: Square(int sideLength) : Rectangle(sideLength, sideLength) {} };
这里Rectangle类是一个具体的实现类,Square类则是一个将Rectangle类进行扩展的类。由于Square类也是一个矩形,所以可以通过public继承Rectangle类来获取Rectangle类中的代码,直接使用Rectangle中的函数GetArea()和GetPerimeter(),而不需要再次实现这些代码。
2. 多态性
public继承还可以用于实现多态性。
例如:
class Animal { public: virtual void Speak() {} }; class Cat : public Animal { public: void Speak() override { std::cout << "Meow" << std::endl; } }; class Dog : public Animal { public: void Speak() override { std::cout << "Woof" << std::endl; } }; void DoSpeak(Animal& animal) { animal.Speak(); } int main() { Cat cat; Dog dog; DoSpeak(cat); DoSpeak(dog); return 0; }
这里Animal类是一个抽象基类,它中包含了一个Speak()虚函数。Cat和Dog类通过public继承Animal类来实现多态性,重写了Animal中的Speak()函数。
在main()函数中,我们创建了一个Cat对象和一个Dog对象,然后将这两个对象分别传递给DoSpeak()函数。由于DoSpeak()函数的参数是Animal的引用,因此cat和dog对象都被作为Animal类型的参数进行了传递。在运行过程中,程序会调用cat和dog的Speak()方法,分别输出Meow和Woof。
3. 接口分离原则
public继承还可以用来实现接口分离原则。接口分离原则指的是,一个接口应该只包含其子类所需要的所有方法和属性,而不应该包含其子类不需要的内容。基于这个原则,我们可以定义多个接口,每个接口代表一种特定的行为,然后在子类中使用public继承来实现多个接口的组合。
例如:
class IReader { public: virtual std::string Read() = 0; }; class IWriter { public: virtual void Write(const std::string& data) = 0; }; class IProcessor { public: virtual void Process() = 0; }; class DataProcessor : public IReader, public IWriter, public IProcessor { public: std::string Read() override { /* implementation */ } void Write(const std::string& data) override { /* implementation */ } void Process() override { /* implementation */ } };
这里我们定义了三个接口:IReader、IWriter和IProcessor。DataProcessor类通过public继承这三个接口,来实现多个接口的组合。
四、结论
public继承是C++中最常见的继承方式之一,它通过在派生类中包含一个基类对象的方式来实现继承。public继承的用途包括代码复用、实现多态性和实现接口分离原则,可以大大提高代码复用性和可维护性。然而,需要注意的是,过度使用public继承可能会导致子类和基类之间产生过于紧密的耦合,降低代码的可扩展性。