【C++】继承和多态、public、private、protected、重写

文章介绍了C++中的继承和多态概念,以及public、protected、private的访问权限。继承允许子类从父类继承属性和方法,多态则是通过虚函数实现同名函数在不同对象上的不同行为。public继承保持成员的原访问权限,protected和private继承则改变成员的访问级别。示例展示了如何使用这些概念实现代码的复用和灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

继承与多态的概念

	面向对象三大原则:封装、继承、多态。
  • 继承是一种机制,通过它一个类可以从另一个类继承属性和方法。派生类(子类)继承基类(父类)的成员函数和数据成员,并且可以在其基础上扩展自己的成员函数和数据成员。C++支持多重继承,即一个派生类可以同时从多个基类中继承。

  • 多态是指同一种操作作用于不同的对象上面,可以有不同的解释,产生不同的执行结果。在C++中,实现多态需要借助虚函数。虚函数是在基类中声明的函数,派生类可以对其进行重写,从而实现不同的功能。当通过指向基类的指针或引用调用虚函数时,程序会根据实际指向的对象类型来调用相应的函数,这种行为称为动态绑定,即在运行时确定调用的函数。

继承与多态的区别与联系

继承是指子类从父类继承属性和方法的过程,子类可以重写(override)父类的方法,以实现自己的特定功能。继承可以简化代码,减少重复的代码量,并且可以通过继承实现代码的复用。

多态是指同一种方法在不同对象上产生不同的行为。在多态的实现中,通常采用父类指针指向子类对象的方式,这样就可以通过父类指针调用子类方法,实现不同的行为。多态可以提高代码的灵活性和可扩展性,使得程序更易于维护和扩展。

区别:

  • 继承是一种代码复用的方式,可以从父类继承属性和方法;多态则是一种代码执行的方式,同一个方法在不同对象上有不同的行为。

  • 继承是一种静态的关系,类在编译时就确定了其继承关系;多态则是一种动态的关系,运行时才能确定具体的行为。

  • 继承是一种自上而下的设计方式,父类是子类的模板;多态则是一种自下而上的设计方式,子类决定了父类的行为。

联系:

  • 继承和多态都是面向对象编程的重要概念,它们都是实现代码复用、提高代码灵活性和可扩展性的重要方式。

  • 多态需要继承作为前提,因为父类指针可以指向子类对象,才能实现多态的效果。

示例

#include <iostream>
using namespace std;

// 基类
class Shape {
   protected:
      int width, height;

   public:
      Shape( int a = 0, int b = 0) {
         width = a;
         height = b;
      }
      virtual int area() {
         cout << "Parent class area :" <<endl;
         return 0;
      }
};

// 派生类
class Rectangle: public Shape {
   public:
      Rectangle( int a = 0, int b = 0):Shape(a, b) { }

      int area () { 
         cout << "Rectangle class area :" <<endl;
         return (width * height); 
      }
};

// 派生类
class Triangle: public Shape{
   public:
      Triangle( int a = 0, int b = 0):Shape(a, b) { }

      int area () { 
         cout << "Triangle class area :" <<endl;
         return (width * height / 2); 
      }
};

int main( ) {
   Shape *shape;
   Rectangle rec(10,7);
   Triangle  tri(10,5);

   // 存储矩形的地址
   shape = &rec;
   // 调用矩形的求面积函数 area
   shape->area();

   // 存储三角形的地址
   shape = &tri;
   // 调用三角形的求面积函数 area
   shape->area();
   
   return 0;
}

结果:

在这里插入图片描述

可以看到,程序中定义了一个基类 Shape 和两个派生类 Rectangle 和 Triangle,两个派生类公有继承基类的属性和方法,并且重写了基类的虚函数 area()。在 main() 函数中,首先创建了一个指向基类的指针 shape,然后将其分别指向 Rectangle 和 Triangle 对象。最后通过指针调用虚函数。shape指针两次调用area方法,但是由于该指针指向的是不同对象,他会根据对象的类型来输出不同的结果,这就是多态

继承和访问的权限

在 C++ 中,类继承分为三种类型:public、protected 和 private。它们分别表示基类成员在派生类中的访问权限:

  • public 继承:基类中的 public 成员在派生类中仍然是 public 的,基类中的 protected 成员在派生类中仍然是 protected 的,基类中的 private 成员仍然是私有的,private成员不能被派生类访问。

  • protected 继承:基类中的 public 成员在派生类中变成 protected 的,基类中的 protected 成员在派生类中仍然是 protected 的,并且只能被他的派生类成员函数和友元函数所访问,基类中的 private 成员不能被派生类访问。

  • private 继承:基类中的 public 和 protected 成员在派生类中变成 private 的,基类中的 private 成员不能被派生类访问。

说明

class Base {
public:
    int a;
protected:
    int b;
private:
    int c;
};

class Derived1 : public Base {
    // a是public的,b是protected的,c不能访问
};

class Derived2 : protected Base {
    // a是protected的,b是protected的,c不能访问
};

class Derived3 : private Base {
    // a是private的,b是private的,c不能访问
};

示例:

#include <iostream>

using namespace std;

class Parent {
public:
    void publicMethod() {
        cout << "This is a public method of Parent class." << endl;
    }

protected:
    void protectedMethod() {
        cout << "This is a protected method of Parent class." << endl;
    }

private:
    void privateMethod() {
        cout << "This is a private method of Parent class." << endl;
    }
};

class Child : public Parent {
public:
    void callParentMethods() {
        publicMethod();     // 公有方法可以在子类中直接访问
        protectedMethod();  // 保护方法可以在子类中直接访问
        // privateMethod();    // 私有方法不能在子类中直接访问
    }
};

int main() {
    Child childObj;
    childObj.publicMethod();     // 公有方法可以在子类对象中直接访问
    // childObj.protectedMethod();  // 保护方法不能在子类对象中直接访问
    // childObj.privateMethod();    // 私有方法不能在子类对象中直接访问

    childObj.callParentMethods(); // 子类中的方法可以调用父类的公有和保护方法

    return 0;
}

在这个示例程序中,Parent类有三个成员方法,分别为publicMethod()protectedMethod()privateMethod(),它们的访问权限分别为public、protected和private。Child类继承了Parent类,并在其中定义了一个方法callParentMethods(),用于调用Parent类的publicMethod()和protectedMethod()方法。在main函数中,我们创建了一个Child类的对象childObj,并演示了不同的访问方式和权限。

结果

在这里插入图片描述

从这个示例程序中可以看出,public成员可以在任何地方被访问,包括在子类中和子类对象中;protected成员只能在子类和子类对象中被访问;private成员只能在类的内部被访问,包括子类中也不能访问。

**提示:**如果把继承方式改为私有继承或保护继承,那么main函数中的

childObj.publicMethod();

语句也会报错,因为保护或私有继承过来之后,公有方法的权限就变了,子类对象不能访问私有或保护的方法,那就更不能访问基类的公有方法了。

结论

在这里插入图片描述

<think>嗯,用户想了解C++中的继承多态接口相关的用法,特别是实现使用教程。首先,我需要回忆一下C++的这些概念。继承是面向对象编程中的一个核心概念,允许子类继承父类的属性方法。多态则是通过虚函数实现的,使得不同子类对象可以对同一方法有不同的实现。接口在C++中通常通过纯虚函数抽象类来实现,类似于Java中的接口。 用户提供的三个引用里提到了一些关键点。引用1提到多态性允许根据对象实际类型调用不同函数版本,这涉及到虚函数表动态绑定。引用2给出了一个具体的代码示例,展示了基类A1派生类B1、C1中的虚函数重写。引用3指出子类可以拥有父类的非私有属性方法,并可以扩展或重写它们。 用户可能需要一个结构化的教程,涵盖基本概念、语法、接口实现方法以及实际应用示例。首先应该解释继承的基本用法,比如公有继承、保护继承私有继承的区别,但通常主要使用公有继承。然后是多态,需要详细说明虚函数的作用,以及如何通过基类指针或引用调用派生类的方法。接口的实现部分需要介绍纯虚函数抽象类,因为C++没有专门的接口关键字,但可以通过纯虚类模拟接口。 接下来要考虑用户可能的疑问点。例如,虚函数表的工作原理,这在引用12中都有涉及,可能需要简要解释。另外,构造函数析构函数在继承中的注意事项,特别是虚析构函数的重要性,避免资源泄漏。还有overridefinal关键字的用法,这些C++11引入的特性可以帮助避免错误,提高代码可读性。 实际应用场景方面,可以举例说明多态在框架设计中的用途,比如插件系统或GUI事件处理,这些地方需要统一的接口但不同的实现。性能方面,可能需要提到虚函数调用会有一定的开销,但通常可以忽略,除非在极端性能敏感的场景。 最后,生成相关问题时,需要考虑用户可能进一步想知道的内容,比如虚函数表的具体结构,多态的性能影响,设计模式中的应用,以及如何避免常见的陷阱如对象切片等。这些问题可以帮助用户深入理解并正确应用这些概念。</think>### C++继承多态详解:接口实现与应用 #### 一、继承基础 1. **核心概念** - 子类继承父类非`private`成员属性方法[^3] - 继承类型:`public`/`protected`/`private`(常用`public`) - 代码示例: ```cpp class Animal { public: void eat() { cout << "Eating" << endl; } }; class Cat : public Animal { public: void meow() { cout << "Meow!" << endl; } }; ``` 2. **内存结构** 子类对象包含父类子对象,内存布局为:父类成员在前,子类新增成员在后[^1] #### 二、多态实现 1. **虚函数机制** - 虚函数声明:`virtual void func()` - 虚函数表(vtable)存储函数指针 - 代码示例: ```cpp class Shape { public: virtual void draw() = 0; // 纯虚函数 virtual ~Shape() {} // 虚析构函数 }; class Circle : public Shape { public: void draw() override { cout << "Drawing circle" << endl; } }; ``` 2. **多态调用** 通过基类指针/引用实现动态绑定: ```cpp Shape* shape = new Circle(); shape->draw(); // 输出"Drawing circle" delete shape; ``` #### 三、接口实现 C++通过纯虚函数实现接口: ```cpp class IPrintable { public: virtual void print() const = 0; virtual ~IPrintable() = default; }; class Document : public IPrintable { public: void print() const override { cout << "Printing document" << endl; } }; ``` #### 四、关键实践技巧 1. **override关键字** 明确表示覆盖父类虚函数,增强代码可读性: ```cpp class Derived : public Base { public: void func() override { ... } }; ``` 2. **虚析构函数** 必须为多态基类声明虚析构函数,防止内存泄漏: ```cpp class Base { public: virtual ~Base() = default; }; ``` 3. **final关键字** 禁止类被继承或方法被重写: ```cpp class FinalClass final { ... }; class Base { public: virtual void func() final { ... } }; ``` #### 五、典型应用场景 1. GUI框架:不同控件统一事件处理接口 2. 插件系统:通过基类接口扩展功能 3. 算法策略:运行时选择不同算法实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嘿♚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值