专业编程基础技术教程

网站首页 > 基础教程 正文

C++中继承、虚函数、抽象类等概念的详解

ccvgpt 2024-11-12 09:53:39 基础教程 4 ℃

类的继承

面向对象编程的 主要目的之一是提供可重用的代码,在开发新的工程的时候,重用经过测试的代码比从头编写和创建好得多,可以节省开发的时间,我们C语言实现代码重用是通过预定义,函数,和C语言的库。在外面c++中提供了更高层次的重用性,有很多的类库因为类库包含了数据表示和类方法,因此c++提供了比库函数更加完整的程序包。我们来原有的类库中拓展和补充自己的想法,就可以实现一些功能,这种通过原有的类扩展出来的新类和原来的类之间的关系我们称之为“继承”,一个新类继承了原有的类。我们接下来 了解一些关于继承之间一些名词:

C++中继承、虚函数、抽象类等概念的详解

1、派生:在已有类的基础上新增之间特性而产生新类的过程叫派生。

2、基类(父类):被继承的已有的类

3、派生类:派生出的新类

继承的作用

我们使用类的继承一个是为了提高我们代码的重用,另外一个就是方便我们的管理,如果不使用继承我们通过拷贝代码同样可以实现对应的功能,但是如果是拷贝代码那么首先代码重用率就会变得很低,重复的代码会让你的工程看起来很庞大,如果拷贝的代码存在某种错误,那么这时候你更改错误的时候你就得每一个地方都改一遍,使用几遍就得改几次,但是如果我们采用继承的方式,代码可以重用,而且维护很方便,如果有错误我们只需要修改一个类中的代码,由他派生出去的类里面的错误也会随着被改变。

继承代码实现:父类A

我简单定义了一个A类,里面的数据成员有姓名、年龄、颜色,我准备用一个A类的派生出两个类来分析我们继承中的一些知识,在父类中定义了一个自己的构造函数,一个显示成员的函数,还有一个虚函数。至于什么是虚函数我们也会在详细解释。

class A
{
  private:
  string name;
  int age;
  string color;
  public:
    A(string name="--",int age=0,string color="--"):name(name),age(age),color(color)
  {  }
  void display()
{
     cout<<name<<"  "<<age<<"  "<<color<<endl;
  }
  virtual void speak()=0;
};

派生类:猫类

由A类派生出来的一个猫的类,我们使用publi继承于A类,在猫类中重用了父类中的成员,我们在猫类中不用定义自己的数据成员,减少了代码量,我们如果有自己的新的数据可以添加。

class cat:public A
{
  public:
  kitiy(string name="--",int age=0,string color="--"):A(name,age,color)
  {  }
  void speak()
{   cout<<"喵喵喵喵!"<<endl;   }
};

派生类:狗类

狗的类也是从A继承出来的,同样也是重用了我们A类中的成员

class dog:public A
{
  public:
  dog(string name="--",int age=0,string color="--"):A(name,age,color)
  {  }
  void speak()
{  cout<<"汪汪!!!!"<<endl;  }
};

主函数main的实现

通过完成上面类的关系之后我们就可以来对各种类进行初始化了,首先声明和初始化了一个狗类,我们知道在class dog中是没有名字、年龄、颜色的成员的,能够使用是因为它继承了我们的A类 。我们在声明和初始化一个猫类。

int main()
{
dog d1("大黄",12,"黄色");
d1.display();
d1.speak();

cat c("小黑",12,"黑色");
c.display();
c.speak();
}

代码结果分析

我们可以看出两个类都成功的初始化了,重用了我们父类A的所有成员,我们可以想象猫类和狗类继承于A类,这意味着猫类和狗类将包含A类中所有的数据成员和函数成员,但是有一点需要注意的是虽然包含了所有但是A类在子类中呈现的形式是没有发生改变的,什么意思呢?就是说A类中私有的成员还是私有的,因为继承并不意味着A类放弃了保护机制,A中的私有成员仍然占有存储空间,只是子类不能直接地访问他们,比如我们猫类或者狗类中不能直接使用(d.name="大黄",d.age=12,d.color="黄色")子类不能直接访问父类的私有成员。只能通过父类的成员函数进行初始化。

虚函数

刚刚我们在上面的代码中用到了虚函数的概念,在这里就结合这个例子和大家说了。什么是我们的虚函数呢?

我们在A类中定义了一个虚函数speak(),虚函数和普通函数在声明上基本没什么区别,只是多了一个关键字 virtual。

virtual void speak()=0;

但是我们并没有写这个函数的实现,而是在子类中子类中把speak这个函数具体化,在这个例子中举例了猫与狗的叫声不一样来区别与说明我们虚函数的作用。在A类中我们声明了这个类中有这种行为,但是具体的行为由子类去根据自己情况实现,猫是“喵喵喵”,我们的狗是“汪汪汪”,我们在调用的时候都是调用了我们的speak()函数,但是不同子类调用的结果却是不一样的。

纯虚函数和抽象类

virtual void speak()=0;

在这个例子中用到的就是纯虚函数,在父类A中声明在子类中实现,纯虚函数和普通虚函数的区别就是函数声明后面的“=0”,在在例子中我们的A类是不能被对象化的,他可以是动物类,但是并不能具体声明出对象来,那么这个类我们就叫抽象类。判断一个类是不是一个抽象类,我们只要看一下这个类里面有没有一个纯虚函数,如果有就是抽象类。

总结

在该文章中,首先讲了我们继承的一些特点以及代码的实现过程,然后讲到了我们虚函数的概念,顺带着提了一下我们的纯虚函数和抽象类,类的继承一个是提高了我们代码的复用,另外一个就是方便我们的管理与维护。

最近发表
标签列表