首页 > 其他分享 >继承与派生(二)

继承与派生(二)

时间:2024-04-01 13:29:05浏览次数:14  
标签:派生 继承 成员 基类 char student 派生类 构造函数

4 私有派生类

在声明一个派生类时,将基类的引用权限指定为private的,该类称为基类的私有派生类。

在私有派生类中,基类的公用成员和保护成员成为派生类中的私有成员,基类的私有成员成为派生类“不可访问的成员”,只有基类的成员函数可以引用它。基类的成员在私有派生类中的引用权限见表15.2。

如果派生类声明首行改为

class student : private stud //声明一个私有派生类

{private:

int age;

char addr[30];

public:

void show( )

{display () //基类的公用成员函数变成派生类的私有函数

cou<<"age: "<<age<<endl; //引用派生类的私有成员,正确。

cout<<" address:"<<addr<<endl:} //引用派生类的私有成员,正确。

void main()

{student a; //定义一个派生类的对象a

a. display( ); //错误。基类的公用成员函数变成派生类私有函数

a.age=18; //错误。外界不能引用派生类的私有成员

可以看到:

(1)不能通过私有派生类对象(如a)引用从基类继承过来的任何成员。

(2)在派生类的成员函数中不能访问基类的私有成员,但可以访问基类的公用成员。

由于私有派生类限制太多,一般不常使用。

5 保护成员

前面已接触过“保护”(protected)这一名词。它和private,public一样是用来声明成员的引用权限的。由protected声明的成员称为保护成员。保护成员不能被外界引用(这点和私有成员类似),但它可以被派生类的成员函数引用。

将表15.1和表15.2综合表示并增加保护成员的内容,见表15.3。

从前面的介绍已知基类的私有成员被派生类(不论是私有派生类还是公用派生类)继承后变为“不可访问的成员”。如果想在派生类引用基类的成员,可以将基类的成员声明为protected。

例15.6 派生类引用保护成员。

class stud //声明基类

{protected;  //基类保护成员

int num;

char name[10];

char sex; //基类公用成员

public:

void display( )

{cou<<"num:"<<num<<endl ;

cout<<"name: "<<name<<endI ;

cout<<"sex: "<<sex<<endl;}

}

class student:public stud //声明一个公用派生类

{

private:

int age;

char addr[30];

public:

void show ( )

{cout<<"num: "<<num<<endl: //引用基类的保护成员,合法。

cout<<"name: "<<name<<endl; //引用基类的保护成员,合法。

cout<<"sex: "<<sex<<endl; //引用基类的保护成员,合法。

cout<<"age:"<<age<<endl; //引用派生类的私有成员,合法。

cout<<"address:"<<addr<<endl:} //引用派生类的私有成员,合法。

}

void main()

{student a; //a是派生类 student 类的对象。

a.show(); //合法。show是派生类中的公用成员函数。

a.num=10023; //错误。外界不能访问保护成员。

}

请与例15.5对比分析。可以看到基类的保护成员对类的外界来说仍然是不可引用的(由于stud中的num是保护成员,外界不能用a.num来引用它),但对派生类来说它相当于私有成员,可以通过成员函数引用。也就是把保护成员的引用范围扩展到派生类中。

6派生类的构造函数

派生类从基类继承了非私有成员函数和数据成员,但是在建立派生类的对象时,系统只执行派生类的构造函数,而不会自动执行基类的构造函数。也就是说,基类的构造函数是不能继承的。如果基类的构造函数包含对变量的初始化,那么在建立派生类的对象时,由于没有执行基类的构造函数,因而就会使基类的变量未初始化。所以在设计派生类的构造函数时,不仅要考虑派生类所增加的变量初始化,还应当考虑基类的变量初始化。在执行派生类的构造函数时,应当调用基类的构造函数。

例15.7派生类的构造函数。

# include<string.h>

# include <iostream.h>

class stud //声明基类

{protected: //保护部分

int num;

char name[10]:

char sex :

public: //公用部分

stud(int n,char nam[],char s) //基类构造函数

{num=n;

strcpy (name,nam);

sex=s;}

~stud( ){ } //基类析构函数

class student: public stud //声明公用派生类student

{ private: //派生类的私有数据

int age;

char addr[30];

public:

student(int n,char nam[],char s,int a, char ad[]):stud(n,nam,s)

{age=a: //在此处只对派生类新增的变量初始化

strcpy(addr.ad); //派生类构造函数

}

void show( )

{ cout<<"num:"<<num<<endl;

cout<<"name:"<<name<<endl;

cout<<"sex: "<<sex<<endl;

cout<<"age:"<<age<<endl;

cout<<" address:"<<addr<<endl :}

~student(){) //派生类析构函数

);

void main( )

{student a(10010,"Wang-li",'f' , 19,"115 Beijing Road, Shanghai* ); 

student b(10011,"Zhang-fun" ,'m’ ,21,"213 Shanghai Road,Beijing" );

a.show( ); //输出第一个学生的数据

b.show( ); //输出第二个学生的数据

请注意派生类构造函数首行的写法:

student (int n, char nam[],char s , int a, char ad[]): stud(n,nam,s)

其一般形式为

派生类构造函数名(参数表列):基类构造函数名(参数表列)

派生类构造函数名后面括号内的参数表列包括参数的类型和参数名,基类构造函数名后面括号内的参数表列只有参数名而不包括参数类型。从基类的声明中可以看到基类构造函数stud 有3个参数(n,nam,s),派生类构造函数student有5个参数,前3个是用来传递给基类构造函数的,后面2个(a和ad)是用来对派生类所增加的变量初始化的。

在 main函数中建立对象a时指定了5个实参。它们按顺序传递给派生类构造函数的形参。然后,派生类构造函数将前面3个传递给基类构造函数的参数。见图15.6。

通过stud (n,nam,s)把3个值再传给基类构造函数,见图15.7。

在上例中也可以将派生类构造函数在类外面定义,而在类的声明中只写该函数的声明:

student (int n, char nam[].char s ,int a, char ad[]);

在类的外面定义派生类构造函数:

student :: student (int n, char nam[],char s . int a, char ad[]): stud(n,nam,s)

{age=a;

strcpy(addr,ad);

}

注意:在类中对派生类构造函数作声明时,不包括基类构造函数名和参数表列(即 stud(n,nam,s))。只在定义函数时才将它列出。

在建立一个对象时,由派生类构造函数先调用基类构造函数,然后再执行派生类构造函数本身。对上例来说,先初始化num,name,sex,然后再初始化age和addr。

在派生类对象消失时,先执行派生类析构函数~student(),再执行其基类析构函数~stud( )。

7继承在软件开发中的重要意义

继承是面向对象技术的一个重要内容。有了继承,使软件的重用成为可能。过去,软件人员开发新的软件,能从已有的软件中直接选用完全符合要求的部件不多,一般都要进行许多修改才能使用,实际上有相当部分要重新编写,工作量很大。继承机制解决了这个问题。将已有的一个类为基础,生成一些派生类(子类),在子类中保存父类中有用的数据和操作,去掉(屏蔽掉)不需要的部分。新生成的子类还可以再生成孙类……而且一个子类可以从多个父类中获得继承(即多继承机制)。编写面向对象的程序时要把注意力放在实现有用的类上面,对已有的类加以整理和分类就有可能使这些类能够被程序设计的许多领域使用。软件设计者可以最大限度地重用已有软件,对已有的类根据需要进行剪裁和修改,在此基础上集中精力编写子类新增加的部分即可。因此有人认为继承是C++和C的最重要的区别之一。

我们只是很简单地介绍了C++面向对象的一些初步知识。面向对象技术和C++的内容很丰富,有许多深入的概念,语法规定也比较复杂,需要花较多的精力和时间去学习和消化。C++最重要的概念是类,其他许多概念都是与类有关的。为了便于理解,我们在本章中没有介绍复杂的程序,所举的例题都是比较简单的,只是为了说明一些概念。正如在本章开始时提到的,只有编写过大程序的人才能真正体会C++的优越性。我们只是希望通过本章的介绍,使读者对C++的特点有初步的了解,为以后系统地学习C++建立一些基础。

标签:派生,继承,成员,基类,char,student,派生类,构造函数
From: https://blog.csdn.net/office_lgirl/article/details/137116722

相关文章

  • 【前端面试3+1】06继承方式及优缺点、缓存策略、url输入到渲染全过程、【二叉树中序遍
    一、继承有哪些方式?以及优缺点        继承的方式包括原型链继承、构造函数继承、组合继承、原型式继承、寄生式继承和组合式继承。1.原型链继承:实现方式:将子类的原型指向父类的实例来实现继承。优点:简单易懂,代码量少。缺点:存在引用类型共享的问题。functionPare......
  • CSS继承性-行高的继承性
    CSS中行高的继承性是CSS继承特性中的一个具体表现。简单来说,如果一个元素(父元素)设置了行高(line-height),那么它的子元素会继承这个行高值,除非子元素本身也设置了行高。行高的继承性有助于保持文本在父子元素之间的一致性和可读性。例如,如果父元素的行高设置为1.5(这通常是相对于......
  • Java继承<一>
    目录继承作用继承概念继承语法访问父类成员变量1.子类和父类不存在同名成员变量2.子类和父类成员变量同名访问父类成员方法1.成员方法名字不同2.成员方法名字相同super关键字继承作用Java中使用类对现实世界中实体来进行描述,类经过实例化之后的产物对象,则可以......
  • 菱形继承与虚基类
    菱形继承会存在多份数据的问题,使用虚继承解决问题虚基类指针vbptr#include<iostream>classAnimal{public:intm_Age;};classSheep:virtualpublicAnimal{public:Sheep(){std::cout<<"sheep"<<std::endl;};};classTu......
  • 继承之同名成员的处理
    #include<iostream>classBase{public:Base(){m_A=100;}voidfunc(){std::cout<<"basefunc"<<std::endl;};intm_A;};classSon:publicBase{public:Son(){m_A=200;......
  • WPF中继承ItemsControl子类控件数据模板获取选中属性
    需求场景列表类控件,如ListBox、ListView、DataGrid等。显示的行数据中,部分内容依靠选中时触发控制,例如选中行时行记录复选,部分列内容控制显隐。案例源码以ListView为例。Xaml部分<ListViewItemsSource="{BindingMyPropertys}"IsManipulationEnabled="False"><List......
  • C++类继承基础5——继承中的类作用域
    继承中的类作用域每个类定义自己的作用域,在这个作用域内我们定义类的成员。当存在继承关系时,派生类的作用域嵌套在其基类的作用域之内。如果一个名字在派生类的作用城内无法正确解析,则编译器将继续在外层的基类作用域中寻找该名字的定义。派生类的作用域位于基类作用域之内......
  • 继承特点、访问特点、方法重写1
    1.继承的特点:①子类可以继承父类的属性和行为,但是子类不能继承父类的构造器;  //子类有自己的构造器,父类构造器用于初始化父类的对象②java是单继承模式,一个类只能继承一个直接父亲;③java不支持多继承、但是支持多层继承;④java所有的的类都是Object的子类;//Java中的所......
  • 深入解析Java继承机制:面向对象编程的核心探究【Java面试题】
    作为一名对技术充满热情的学习者,我一直以来都深刻地体会到知识的广度和深度。在这个不断演变的数字时代,我远非专家,而是一位不断追求进步的旅行者。通过这篇博客,我想分享我在某个领域的学习经验,与大家共同探讨、共同成长。请大家以开放的心态阅读,相信你们也会在这段知识之......
  • C++继承详解
    文章目录前言一、继承的概念二、基类和派生类对象赋值转换三、继承中的作用域,隐藏四、菱形继承,菱形虚拟继承五、子类的默认成员函数六.继承和组合总结前言在本篇文章中我们将会学到有关继承方面的知识,其中C++中三大特性分别为:封装,继承多态。由此可见继承在学习中的......