小众知识

首页 > 正文

一个面试的问题

派生和继承有什么相同点,和不同点?
请教!  

1、相关概念
在C++中可重用性(software reusability)是通过继承(inheritance)这一机制来实现的。一个新类从已有的类那里获得其已有特性,这种现象称为类的继承。从已有的类(父类)产生一个新的子类,称为类的派生。派生类是基类的具体化,而基类则是派生类的抽象。
基类名前面有public的称为“公用继承(public inheritance)”。
声明派生类的一般形式为
class 派生类名: [继承方式] 基类名
{
派生类新增加的成员
} ;
继承方式包括: public(公用的),private(私有的)和protected(受保护的),此项是可选的,如果不写此项,则默认为private(私有的)。所谓公用的,是说所定义的变量或函数在类外可以引用,而私有的,则说明定义的变量或函数只能在类内使用,受保护的意为不能被外界引用,但可以被派生类的成员引用。
20、继承和派生(一) - EdwardLewis - 墨涵天地
    构造一个派生类包括以下3部分工作: 
(1) 从基类接收成员。派生类把基类全部的成员(不包括构造函数和析构函数)接收过来。
(2) 调整从基类接收的成员。接收基类成员是程序人员不能选择的,但是程序人员可以对这些成员作某些调整。
(3) 在声明派生类时增加的成员。
此外,在声明派生类时,一般还应当自己定义派生类的构造函数和析构函数,因为构造函数和析构函数是不能从基类继承的。
在派生类中,成员有4种不同的访问属性:  
① 公用的,派生类内和派生类外都可以访问。
② 受保护的,派生类内可以访问,派生类外不能访问,其下一层的派生类可以访问。
③ 私有的,派生类内可以访问,派生类外不能访问。
④ 不可访问的,派生类内和派生类外都不能访问。
2、继承方式
(1) 公用继承(public inheritance)基类的公用成员和保护成员在派生类中保持原有访问属性,其私有成员仍为基类私有。
(2) 私有继承(private inheritance)基类的公用成员和保护成员在派生类中成了私有成员。其私有成员仍为基类私有。
(3) 受保护的继承(protected inheritance)基类的公用成员和保护成员在派生类中成了保护成员,其私有成员仍为基类私有。保护成员的意思是: 不能被外界引用,但可以被派生类的成员引用。
在定义一个派生类时将基类的继承方式指定为protected的,称为保护继承,用保护继承方式建立的派生类称为保护派生类(protected derived class),其基类称为受保护的基类(protected base class),简称保护基类。
20、继承和派生(一) - EdwardLewis - 墨涵天地
stud.display( ); //调用基类的公用成员函数,输出基类中数据成员的值
stud.display_1();//调用派生类的公用成员函数,输出派生类中数据成员的值
    对于不需要再往下继承的类的功能可以用私有继承方式把它隐蔽起来,这样,下一层的派生类无法访问它的任何成员。可以知道: 一个成员在不同的派生层次中的访问属性可能是不同的。它与继承方式有关。
私有继承和保护继承方式在使用时需要十分小心,一般不常用。在实际中,常用的是公用继承。
基类的私有成员被派生类继承后变为不可访问的成员,派生类中的一切成员均无法访问它们。如果需要在派生类中引用基类的某些成员,应当将基类的这些成员声明为protected,而不要声明为private。
20、继承和派生(一) - EdwardLewis - 墨涵天地
3、继承类型
1)单继承
一个派生类只从一个基类派生,这称为单继承(single inheritance)。
2)多继承
一个派生类有两个或多个基类的称为多重继承(multiple inheritance)。应避免深层次继承和多继承。
如:
class D:public A,private B,protected C
{类D新增加的成员}
构造函数形式为:
派生类构造函数名(总参数表列): 基类1构造函数(参数表列), 基类2构造函数(参数表列), 基类3构造函数 (参数表列)
{派生类中新增数成员据成员初始化语句}
       各基类的排列顺序任意。派生类构造函数的执行顺序同样为: 先调用基类的构造函数,再执行派生类构造函数的函数体。调用基类构造函数的顺序是按照声明派生类时基类出现的顺序。
 Graduate(string nam,int a,char s, string t,float sco,float w):
        Teacher(nam,a,t),Student(nam,s,sco),wage(w) { }
nam赋给了Teacher和Student两个类的名字属性,实质上是一个人。
而在成员函数中引用数据成员时指明其作用域,如
cout<<″name:″<A)二义性问题
(1) 两个基类有同名成员
20、继承和派生(一) - EdwardLewis - 墨涵天地
可以用基类名来限定:
c1.A::a=3;          //引用c1对象中的基类A的数据成员a
c1.A::display();      //调用c1对象中的基类A的成员函数display
20、继承和派生(一) - EdwardLewis - 墨涵天地
(2)两个基类和派生类三者都有同名成员
 基类的同名成员在派生类中被屏蔽,成为“不可见”的。
c1.display( ); 
c1.A::display();     //表示是派生类对象c1中的基类A中的成员函数display
c1.B::display();     //表示是派生类对象c1中的基类B中的成员函数display
20、继承和派生(一) - EdwardLewis - 墨涵天地
(3) 如果类A和类B是从同一个基类派生的
20、继承和派生(一) - EdwardLewis - 墨涵天地
20、继承和派生(一) - EdwardLewis - 墨涵天地
c1.A::a=3; c1.A::display();//要访问的是类N的派生类A中的基类成员
4、派生类的访问属性
(1) 基类的成员函数可以访问基类成员。
(2) 派生类的成员函数可以访问派生类自己增加的成员。
(3) 基类的成员函数访问派生类的成员:
基类的成员函数只能访问基类的成员,而不能访问派生类的成员
(4) 派生类的成员函数访问基类的成员:
如继承中所讨论的。
(5) 在派生类外访问派生类的成员:
在派生类外可以访问派生类的公用成员,而不能访问派生类的私有成员。
(6) 在派生类外访问基类的成员:
如继承中所讨论的。
5、派生类的构造函数和析构函数
在设计派生类的构造函数时,不仅要考虑派生类所增加的数据成员的初始化,还应当考虑基类的数据成员初始化:在执行派生类的构造函数时,调用基类的构造函数。
简单的派生类只有一个基类,而且只有一级派生(只有直接派生类,没有间接派生类),在派生类的数据成员中不包含基类的对象(即子对象)。
1)简单的派生类的构造函数
其一般形式为
派生类构造函数名(总参数表列): 基类构造函数名(参数表列)
  {派生类中新增数据成员初始化语句}

Student1(int n,string nam,char s,int a,string ad):Student(n,nam,s) 
 //派生类构造函数
{age=a;   //在函数体中只对派生类新增的数据成员初始化
 addr=ad;
}
在类中对派生类构造函数作声明时,不包括基类构造函数名及其参数表列,只在定义函数时才将它列出。
不仅可以利用初始化表对构造函数的数据成员初始化,而且可以利用初始化表调用派生类的基类构造函数,实现对基类数据成员的初始化。也可以在同一个构造函数的定义中同时实现这两种功能。
Student1(int n, string nam,char s,int a, string ad): Student(n,nam,s), age(a),addr(ad){}
执行构造函数的顺序是: ①派生类构造函数先调用基类构造函数;②再执行派生类构造函数本身(即派生类构造函数的函数体)。
在派生类对象释放时,先执行派生类析构函数~Student1( ),再执行其基类析构函数~Student( )。
2)有子对象的派生类的构造函数
定义派生类构造函数的一般形式为
派生类构造函数名(总参数表列): 基类构造函数名(参数表列),子对象名(参数表列)
  {派生类中新增数成员据成员初始化语句}
执行派生类构造函数的顺序是: 
① 调用基类构造函数,对基类数据成员初始化;
② 调用子对象构造函数,对子对象数据成员初始化;
③ 再执行派生类构造函数本身,对派生类数据成员初始化。
派生类构造函数的总参数表列中的参数,应当包括基类构造函数和子对象的参数表列中的参数。基类构造函数和子对象的次序可以是任意的,如果有多个子对象,派生类构造函数的写法依此类推,应列出每一个子对象名及其参数表列。

  Student1(int n, string nam,int n1, string nam1,int a, string ad)
      :Student(n,nam),monitor(n1,nam1) //派生类构造函数
      {......}
#include 
#include 
using namespace std;
class Student
{
public:
Student(int n,string nam)
{
num=n;
name=nam;
}
void display()
{
cout<<"num:"<
3)多层派生时的构造函数
 Student1(int n,char nam[10],int a):Student(n,nam)//派生类构造函数
 Student2(int n, string nam,int a,int s):Student1(n,nam,a)
在声明Student2类对象时,调用Student2构造函数;在执行Student2构造函数时,先调用Student1构造函数;在执行Student1构造函数时,先调用基类Student构造函数。初始化的顺序是: 
① 先初始化基类的数据成员。
② 再初始化Student1的数据成员。
③ 最后再初始化Student2的数据成员。
当不需要对派生类新增的成员进行任何初始化操作时,派生类构造函数的函数体可以为空,即构造函数是空函数
Student1(int n, strin nam,int n1, strin nam1):Student(n,nam),
monitor(n1,nam1) { }
      如果在基类中没有定义构造函数,或定义了没有参数的构造函数,那么在定义派生类构造函数时可不写基类构造函数。
4)派生类的析构函数 
    在派生时,派生类不能继承基类的析构函数,需要通过派生类的析构函数去调用基类的析构函数。在派生类中可以根据需要定义自己的析构函数,用来对派生类中所增加的成员进行清理。在执行派生类的析构函数时,系统会自动调用基类的析构函数和子对象的析构函数,对基类和子对象进行清理。调用的顺序与构造函数相反: 先执行派生类自己的析构函数,对派生类新增加的成员进行清理,然后调用子对象的析构函数,最后调用基类的析构函数。

 zysdl 发表于:2002-12-11 15:57:39
得分:0 

派生=继承 ? 

 cenlmmx 发表于:2002-12-11 16:17:25
得分:0 

派生有父类到子类,
继承有单继承和多继承.

不太好说,大家说说. 

 Cybergate 发表于:2002-12-11 16:33:21
得分:0 

继承的英文是Derive, 派生呢? 

 J_John 发表于:2002-12-11 18:17:33
得分:0 

不同吗?谁出的题目? 

 zysdl 发表于:2002-12-11 18:24:44
得分:0 

inherit=继承
Derive=派生 

 zjw2723114 发表于:2002-12-11 18:31:16
得分:0 


区别:

继承指“继承公共的接口”,至于不同父类另外定义的一些自身功能与继承无关
派生不仅继承公共的接口,而且已有包括定义出一些自身的功能 

 wsmall 发表于:2002-12-11 20:17:52
得分:0 

向已有的类添加了新的功能后的类叫做原来的类的派生。原来的类叫做新类的基类,看这个派生的定义不就是继承的定义吗? 

 elderpig 发表于:2002-12-12 10:04:04
得分:0 

继承与派生是站在继承关系的不同类上而言:
父类(基类)“派生”出子类(派生类);
子类(派生类)“继承”了父类(基类) 

 ElleLang 发表于:2002-12-12 10:30:41
得分:0 

咬文嚼字,你死定了 

 davidshen 发表于:2002-12-12 20:32:28
得分:0 

我也觉得这个问题问的,的确是无话可说了。 

 leialen 发表于:2002-12-12 20:43:48
得分:0 

无话可说! 

 fzel_net 发表于:2002-12-12 20:50:05
得分:0 

c++prime  好象讲了 

 davidshen 发表于:2002-12-15 15:35:04
得分:0 

说说,俺想听听。
楼上的兄弟。 

 zhaoyifei1 发表于:2002-12-15 16:21:49
得分:0 

无聊的问题,继承是特性,派生是动作,我才疏学潜,只当是抛砖引玉。thanks 

 zhaoyifei1 发表于:2002-12-15 16:24:44
得分:0 

继承的英文是:inheritance 

 xyc000 发表于:2002-12-24 14:45:42
得分:0 

对同样事情的不同角度的描述:
向下是派生,向上是继承 

 liujinzhou 发表于:2002-12-24 14:51:03
得分:0 

不知道,关注 

 chinajiji 发表于:2002-12-24 14:58:22
得分:0 

这个题出得太臭,哪个公司出的? 

 JoshuaLi 发表于:2002-12-25 15:26:03
得分:0 

考中文吗?比画不一样多 

 furnace 发表于:2002-12-25 15:36:07
得分:0 

感觉没有什么意思的问题

btw:
to  cenlmmx(mm)
派生有父类到子类,
继承有单继承和多继承.
      ^^^^^^^^^^^^^^
这个如果但单说是继承而不限定是什么语言的话是不正确的,在C++里面是有多继承,而别的面向对象语言例如Java 就只有单继承。

 21bird 发表于:2002-12-29 22:05:03
得分:0 

一些普通的书(我不知道是不是算垃圾书)里面,继承和派生好像是一个意思。 

上一篇:两层电梯变三层!
下一篇:不是问技术问题,就算是送分吧 ^_^

分享到: