多态性
10.2 典型例题分析与解答
例题1:指出下列对定义重载函数的要求中,哪些是错误的提法。
A.要求参数的个数不同。 B.要求参数中至少有一个类型不同。
C.求函数的返回值不同。 D. 要求参数的个数相同时,参数类型不同。答案:C
例题3:下面关于友元的描述中,错误的是()。
A. 友元函数可以访问该类的私有数据成员
B. 一个类的友元类中的成员函数都是这个类的友元函数
C. 友元可以提高程序的运行效率
D. 类与类之间的友元关系可以继承
答案:D
例题4:下述静态成员的特性中,()是错误的。
A. 静态成员函数不能利用this指针
B. 静态数据成员要在类体外进行初始化
C. 引用静态数据成员时,要在静态数据成员名前加<类名>和作用域运算符
D. 静态数据成员不是所有对象所共有的
答案:D
例题5:关于虚函数的描述中,()是正确的。
A. 虚函数是一个静态成员函数
B. 虚函数是一个非成员函数
C. 虚函数既可以在函数说明时定义,也可以在函数实现时定义
D. 派生类的虚函数与基类中对应的虚函数具有相同的参数个数和类型
参考答案:D
例题11:分析下列程序的输出结果。
#include
class A{
public:
A() { cout<<"A's cons."< virtual ~A() { cout<<"A's des."< }; class B : public A{ public: B() { f(); cout<<"B's cons."< ~B() { cout<<"B's des."< class C : public B{ public: C() { cout<<"C's cons."< void f() { cout<<"C's f()."< void main() { A *a=new C; a->g(); delete a; } 运行结果: A's cons. A's f(). B's cons. C's cons. C's f(). C's des. B's des. A's des. 10.3 教材习题解答 1.选择题 (1)下列关于动态联编的描述中,错误的是()。 A.动态联编是以虚函数为基础 B.动态联编是运行时确定所调用的函数代码的 C.动态联编调用函数操作是指向对象的指针或对象引用 D.动态联编是在编译时确定操作函数的 答案:D (2)关于虚函数的描述中,正确的是()。 A.虚函数是一个静态成员函数 B.虚函数是一个非成员函数 C.虚函数即可以在函数说明定义,也可以在函数实现时定义 D.派生类的虚函数与基类中对应的虚函数具有相同的参数个数和类型答案:D (3)下面4个选项中,()是用来声明虚函数的。 A.virtual B.public C.using D.false 答案:A (4)编译时的多态性可以通过使用( )获得。 A.虚函数和指针 B.重载函数和析构函数 C.虚函数和对象 D.虚函数和引用 答案:A (5)关于纯虚函数和抽象类的描述中,错误的是()。 A.纯虚函数是一种特殊的虚函数,它没有具体的实现 B.抽象类是指具体纯虚函数的类 C.一个基类中说明有纯虚函数,该基类派生类一定不再是抽象类 D.抽象类只能作为基类来使用,其纯虚函数的实现由派生类给出 答案:B (6)下列描述中,()是抽象类的特征。 A.可以说明虚函数 B.可以进行构造函数重载 C.可以定义友元函数 D.不能说明其对象答案:D (7)以下()成员函数表示虚函数。 A.virtual int vf(int); B.void vf(int)=0; C.virtual void vf()=0; D.virtual void vf(int) { }; 答案:D (8)如果一个类至少有一个纯虚函数,那么就称该类为( A )。 A.抽象类 B.虚函数 C.派生类 D.以上都不对 答案:A (9)要实现动态联编,必须通过()调用虚函数。 A.对象指针 B.成员名限定 C.对象名 D.派生类名答案:A (10)下面描述中,正确的是(A )。 A.virtual可以用来声明虚函数 B.含有纯虚函数的类是不可以用来创建对象的,因为它是虚基类 C.即使基类的构造函数没有参数,派生类也必须建立构造函数 D.静态数据成员可以通过成员初始化列表来初始化 答案:A 2.什么叫做多态性?在C++语言中是如何实现多态的? 答:多态是指同样的消息被不同类型的对象接收时导致完全不同的行为,是对类的特定成员函数的再抽象.c十+支持的多态有多种类型.重载(包括函数重载和运算符重载)和虚函数是其中主要的方式. 3.什么叫做抽象类?抽象类有何作用?抽象类的派生类是否一定要给出纯虚函数? 答:带有纯虚函数的类是抽象类.抽象类的主要作用是通过它为一个类族建立一个公共的接口.使它们能够更有效地发挥多态特性。抽象类声明了一组派生类共同操作接口的通用语义.面接口的完整实现,即纯虚函数的函数体,要由派生类自己给出.但抽象类的派生类并非一定要给出纯虚函数的实现.如果派生类没有给出纯虚函数的实现,这个派生类仍然是一个抽象类. 4.声明一个参数为整型、无返回值、名为fun1的虚函数。 答: virtual void fnl(int); 5.在C++语言中,能否声明虚构造函数?为什么?能否声明虚析构函数?有何用途? 答:在C++-中不能声明虚构造函数.多态是不同的对象对同一消息有不同的行为特性.虚函数作为运行过程中多态的基础,主要是针对对象的,面构造函数是在对盘产生之前运行的,因此虚构造函数是没有童义的.在C++中可以声明虚析构函数.析构函数的功能是在该类对象消亡之前进行一些必要的清理工作,如果一个类的析构函数是虚函数,那么,由它派生而来的所有子类的析构函数也是虚函数.析构函数设置为虚函数之后,在使用指针引用时可以动态联编,实理运行时的多态,保证使用基类的指针就能够谓用适当的析构函数指针对不同的对象进行清理工作. 10.声明一个Shape抽象类,在此基础上派生出Rectangle和Circle类,二者都有GetArea( )函数计算对象的面积,GetPerim( )函数计算对象的周长。 解答: #include #include class shape { public: virtual void getarea()=0; virtual void getperim()=0; }; class rectangle:public shape { int a,b,c; double s,p; public: rectangle(int a1,int b1,int c1) {a=a1;b=b1;c=c1;} void getperim() { p=a+b+c; cout<<"周长 "< void getarea() { p=(a+b+c)/2.0; s=sqrt(p*(p-a)*(p-b)*(p-c)); cout<<"面积"< } }; class circle :public shape { float r,s,p; public: circle(float r1) {r=r1;} void getperim() { p=2*r*3.1415926;cout<<"周长 "< void getarea() { s=r*r*3.1415926; cout<<"面积"< void show(shape *p) { p->getarea(); p->getperim(); } void main() { shape *p; rectangle a(3,4,5); circle b(10); p=&a; show(p); p=&b; show(p); } 10.4 补充习题 (6)有如下类的定义。空格处的语句是()。 class MyClass {public: MyClass(int a = 0, int b = 0){ X = a;Y = b; } void Change() const {X -= 10; Y += 10; } private: () int X, Y; }; A. static B. const C. mutable D.不需要填入内容 (7)编译时的多态性可以通过使用()获得。 A.虚函数和指针B.重载函数和析构函数 C.虚函数和对象 D.虚函数和引用2.填空 (1).单目运算符作为类成员函数重载时形参;双目运算符作为重载时需声明其右操作数,作为重载时需声明全部操作数。 10.根据给定的程序执行结果,将下列程序补充完整。 #include class Base {public: Base(int i) {b=i;} (1) protected: int b; }; class Derive1:public Base {public: (2) void Print(){cout<<"Derive1's Print() called."< class Derive2:public Base {(3) }; void fun((4)){ obj->Print();} void main() { (5) fun(d1); fun(d2); } 程序的执行结果如下:Derive1's Print() called. Derive2's Print() called. #include {public: Base(int i) {b=i;} virtual void Print(){}; protected: int b; }; class Derive1:public Base {public: Derive1():Base(1){}; void Print(){cout<<"Derive1's Print() called."< class Derive2:public Base {public: Derive2():Base(1){}; void Print(){cout<<"Derive2's Print() called."< void fun(Base *obj){obj->Print();} void main() {Base *d1=new Derive1; Base *d2=new Derive2; fun(d1); fun(d2); } Java 程序设计练习题(1) 一、单项选择题 1.下面( B )是合法的 Java 标识符。 A、#_pound B、_underscore C、5Interstate D 、 class 2.下面( D )赋值语句不会出现编译警告或错误。 A、float f=1.3; B、char c="a"; C、byte b=257; D、int i=10; 3.编译一个定义了两个类和三个方法的 Java 源程序文件,总共会产生( D )个字节码文件。 A、5 个字节码文件,以“.java”为扩展名 B、2 个字节码文件,以“.java”为扩展名 C、5 个字节码文件,以“.class”为扩展名 D、2 个字节码文件,以“.class”为扩展名4.有关类的说法,正确的是( B )。 A、类具有封装性,所以类的数据是不能被访问的 B、类具有封装性,但可以通过类的公共接口访问类中的数据 C、声明一个类时,必须使用 public 修饰符 D、每个类中必须有 main 方法,否则程序无法运行 5.执行完下面程序片段后,( B )的结论是正确的。 int a, b, c; a = 1; b = 2; c = (a + b > 3 ? a++ : b++); A、a 的值是 2,b 的值是 3 B、a 的值是 1,b 的值是 3 C、a 的值是 1,b 的值是 2 D、c 的值是 false 6.将类的成员的访问权限设置为默认的,则该成员能被( A )。 A、同一包中的类访问 B、其他包中的类访问 C、所有的类访问 D、所有的类的子类访问 7.下面的方法重载,正确的是( C )。 A、int fun(int a, float b) { } B、float fun(int a, float b) { } float fun(int a, float b) { } float fun(int x, float y) { } C、float fun(float a) { } D、float fun1(int a, float b) { } float fun(float a, float b) { } float fun2(int a, float b) { } 8.下面关于继承的说法,正确的是( D )。 A、超类的对象就是子类的对象 B、一个类可以有几个超类 C、一个类只能有一个子类 D、一个类只能有一个超类 9.下面关于多态性的说法,正确的是( C )。 A、一个类中不能有同名的方法 第八章群体遗传学(答案) 一、选择题 (一)单项选择题 *1. 基因库是: A.一个体的全部遗传信息B.一孟德尔群体的全部遗传信息C.所有生物个体的全部遗传信息D.所有同种生物个体的全部遗传信息E.一细胞内的全部遗传信息 2. 一个有性生殖群体所含的全部遗传信息称为: A.基因组B.基因文库C.基因库D.基因频率 E.基因型频率 *3. 一个遗传不平衡的群体随机交配()代后可达到遗传平衡。 A.1代B.2代C.2代以上D.无数代E.以上都不对 4. 在10000人组成的群体中,M型血有3600人,N型血有l600人.MN型血有4800人,该群体是: A.非遗传平衡群体B.遗传平衡群体C.χ2检验后,才能判定 D.无法判定 E. 以上都不对 *5.遗传平衡定律适合: A.常染色体上的一对等位基因B.常染色体上的复等位基因C.X-连锁基因D.A+B E.A+B+C *6.不影响遗传平衡的因素是: A.群体的大小B.群体中个体的寿命C.群体中个体的大规模迁移 D.群体中选择性交配E.选择 7.已知群体中基因型BB、Bb和bb的频率分别为40%,50%和10%,b基因的频率为:A.0.65 B.0.45 C.0.35 D.0.30 E.0.25 8.先天性聋哑(AR)的群体发病率为0.0004,该群体中携带者的频率是: A.0.01 B.0.02 C.0.0002 D.0.04 E.0.1 9. PTC味盲为常染色体隐性性状,我国汉族人群中PTC味盲者占9%,相对味盲基因的显性基因频率是: A.0.09 B.0.49 C.0.42 D.0.7 E.0.3 *10.下列哪项不会改变群体的基因频率: A.群体变为很小B.群体内随机交配C.选择放松 D.选择系数增加E.突变率的降低 11. 最终决定一个体适合度的是: A.健康状况B.寿命C.性别D.生殖能力E.生存能力 12. 随着医疗技术的进步,某种遗传病患者经治疗,可以和正常人一样存活并生育子女,若干年后,该疾病的变化是: A.无变化 B.发病率降低 C.发病率升高D.突变率升高E.发病率下降到零 13. 选择放松使显性致病基因和隐性致病基因频率: A.同样的速度增加 B. 同样的速度降低 C. 显性致病基因频率增加快,隐性致病基因频率增加慢D.显性致病基因频率降低快,隐性基因频率降低慢 E. 二者那不变 14. 近亲婚配后代常染色体隐性遗传病的发病风险提高的倍数与致病基因频率q的关系是: A. q越大,提高的倍数越多 B. q越小,提高的倍数越多C.提高的倍数与q无关D.无论q的大小,提高的倍数都一样E.以上都不对 *15.遗传平衡群体保持不变的是: A.基因频率B.基因型频率C.群体的大小D.群体的适合范围E.A十B *16.一对夫妇表型正常,妻子的弟弟是白化病(AR)患者。假定白化病在人群中的发病率为1/10000,这对夫妇生下白化病患儿的概率是: A.1/4 B.1/100 C.1/200 D.1/300 E.1/400 17.下列处于遗传平衡状态的群体是: A.AA:0.20;Aa:0.60;aa:0.20 B.AA:0.25;Aa:0.50;aa:0.25 C.AA:0.30;Aa:0.50;aa:0.20 D.AA:0.50;Aa:0;aa:0.50 E.AA:0.75;Aa:0.25;aa:0 福建农林大学实验报告 实验6 多态性(一) 一、实验目的和要求 (1)掌握虚函数的定义与使用方法,进一步理解多态性的概念和分类。 (2)了解纯虚函数和抽象类的使用方法。 二、实验内容和原理 1、分析并调试下列程序,回答以下问题:(1)指出抽象类(2)指出虚函数,并说明它的作用(3)每个类的作用是什么?整个程序的作用是什么? 2、使用虚函数编写程序求球体、圆柱体和圆锥的体积,由于球体、圆柱体和圆锥都可以看做由圆继 承而来,所以可以定义圆类作为基类。在圆类中定义数据成员半径和一个求体积的虚函数。由圆类 派生出球体类、圆柱体类和圆锥类,在派生类中对圆类中的虚函数重新定义。编写一个外部函数求 各类形状的总体积。最后在main()函数中构造若干形状,并求它们的体积和。 三、实验环境 1. 硬件:PC机; 2. 软件:Windows操作系统、Visual C++ 6.0 四、算法描述及实验步骤 1、算法描述及步骤如下: (1)根据题目要求编写好程序代码并在VC环境下输入源程序。 (2)检查程序有无错误(包括语法错误和逻辑错误),有则改之。 (3)编译和连接,仔细分析编译信息,如有错误应找出原因并改正之。本题改正后的代码如下: #include 继承与多态习题 一.基本概念与基础知识自测题 8.1填空题 8.1.1 如果类α继承了类β,则类α称为(1)类,而类β称为(2)类。(3)类 的对象可作为(4)类的对象处理,反过来不行,因为(5)。如果强制转换则要注意(6)。 答案:(1)基类 (2)派生类 (3)派生类 (4)基类 (5)派生类有一些新成员 (6)只能派生类强制转换为基类 8.1.2 当用public继承从基类派生一个类时,基类的public成员成为派生类的(1)成员, protected成员成为派生类的(2)成员,对private成员是(3)。公有派生可以使其类的(4),所以公有派生是主流。 答案:(1)public成员 (2)protected成员 (3)不可访问 (4)接口不变 8.1.3 利用继承能够实现(1)。这种实现缩短了程序开发的时间,VC++中的(2)很 好地体现了这一点。 答案:(1)代码的复用 (2)MFC编程 8.1.4 一个派生类只有一个直接基类的情况称为(1),而有多个直接基类的情况称为 (2)。继承体现了类的(3)概念,这在MFC中得到了很好表现,MFC中只采用了(4)。 答案:(1)单继承 (2)多重继承 (3)层次 (4)单继承 8.1.5 C++中多态性包括两种多态性:(1)和(2)。前者是通过(3)实现的, 而后者是通过(4)和(5)来实现的。 答案:(1)编译时的 (2)运行时的 (3)函数和运算符的重载 (4)类继承关系 (5)虚函数 8.1.6 在基类中将一个成员函数说明成虚函数后,在其派生类中只要(1)、(2)和 (3)完全一样就认为是虚函数,而不必再加关键字(4)。如有任何不同,则认为是(5)而不是虚函数。除了非成员函数不能作为虚函数外,(6)、(7)和(8)也不能作为虚函数。 答案:(1)同虚函数名 (2)同参数表 (3)同返回类型。如基类中返回基类指针,而派生类中返回派生类指针是允许的 (4)virtual (5)重载 (6)静态成员函数 (7)内联函数 (8)构造函数 8.1.7 纯虚函数定义时在函数参数表后加(1),它表明程序员对函数(2),其本质 是将指向函数体的指针定为(3)。 答案:(1)=0 (2)不定义 (3)NULL 8.2简答题 8.2.1构造函数和析构函数可以继承吗?派生类构造函数各部分的执行次序是怎样的?答:构造函数和析构函数不可以继承。派生类构造函数各部分的执行次序是: 1.调用基类构造函数,按它们在派生类声明的先后顺序,依次调用。 2.调用新增成员对象的构造函数,按它们在类定义中声明的先后顺序,依次调用。 3.派生类的构造函数体中的操作。 8.2.2什么叫派生类的同名覆盖(override)? 答:如果派生类声明了一个和某个基类成员同名的新成员(当然如是成员函数,参数表也必须一样,否则是重载),派生类中的新成员就屏蔽了基类同名成员,类似函数中的局部变量屏蔽全局变量。称为同名覆盖(override)。 8.2.3派生类的析构函数中需完成什么任务?是否要编写对基数和成员对象的析构函数的 调用?为什么? 答:析构函数的功能是作善后工作,析构函数无返回类型也没有参数,情况比较简单。派生类析构函数定义格式与非派生类无任何差异,不要编写对基数和成员对象的析构函数的调用,只要在函数体内把派生类新增一般成员处理好就可以了,因为对新增的成员对象和基类的善后工作,系统会自己调用成员对象和基类的析构函数来完成。 8.2.4为什么要使用虚基类?怎样定义虚基类?用一个实例来解释虚基类在其派生类中的 存储方式。 答:在多重继承是有可能出现同一基类的两个拷贝,为避免这种情况,可使用虚基类。虚基类(virtual base class)定义方式如下: class派生类名:virtual 访问限定符基类类名{...}; class派生类名:访问限定符virtual基类类名{...}; virtual 关键字只对紧随其后的基类名起作用。 C++的封装性、继承性和多态性概念 封装的目的是增强安全性和简化编程,使用者不必了解具体的实现细节,而只是要通过外部接口,一特定的访问权限来使用类的成员。例如,在抽象的基础上,我们可以将时钟的数据和功能封装起来,构成一个时钟类。按c++的语法,时钟类的声明如下:class Clock { public: //共有成员,外部借口void SetTime(int NewH,int NewM,int NewS); void ShowTime(); private: //私有成员,外部无法访问int Hour,Minute,Second; } 可以看到通过封装使一部分成员充当类与外部的接口,而将其他的成员隐蔽起来,这样就达到了对成员访问权限的合理控制,使不同类之间的相互影响减少到最低限度,进而增强数据的安全性和简化程序的编写工作。什么是多态(Polymorphisn)?按字面的意思就是“多种形状”。引用Charlie Calverts对多态的描述——多态性是允许你将父对象设置成为和一个或更多的他的子对象相等 的技术,赋值之后,>>>父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作<<<(摘自“Delphi4 编程技术内幕”)。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。多态性在Object Pascal和C++中都是通过虚函数(Virtual Function)实现的。好,接着是“虚函数”(或者是“虚方法”)。虚函数就是允许被其子类重新定 义的成员函数。而子类重新定义父类虚函数的做法,称为“覆盖”(override),或者称为“重写”。“继承”是面向对象软件技术当中的一个概念。如果一个类A继承自另一个类B,就把这个A称为"B的子类",而把B称为"A的父类"。继承可以使得子类具有父类的各种属性和方法,而不需要再次编写相同的代码。在令子类继承父类的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类的原有属性和方法,使其获得与父类不同的功能。 ... 继承是指一个对象直接使用另一对象的属性和方法。事实上,我们遇到的很多实体都有继承的含义。例如,若把汽车看成一个实体,它可以分成多个子实体,如:卡车、公共汽车等。这些子实体都具有汽车的特性,因此,汽车是它们的"父亲",而这些子实体则是汽车的"孩子"。19. 多态的作用?主要是两个:1. 隐藏实现细节,使得代码能够模块化;扩展代码模块,实现代码重用; 2. 接口重用:为了类在继承和派生的时候,保证使用家族中任一类的实例的某一属性时的正确调用。 第八章主要组织相容性复合体 学时:2 目的要求: 1.掌握:主要组织相容性复合体的概念,基因构成。HLA分子的分布,结构和功能。 2.熟悉:HLA分子表的影响因素,HLA多态性的遗传基础,HLA在医学上的意义。 3.了解:非经典HLA分子,HLA分型。 教学内容: 1.MHC的概念和基因构成:小鼠H-2复合体和人类HLA复合体。 2.HLA-I类和II类分子的分布、结构和功能。非经典HLA分子的功能。HLA分子表达的影响因子。 3.HLA多态性的遗传基础。 4.HLA在医学上的意义-与器官移植,免疫应答及疾病的关系。 [本章主要内容] 一、概述 20世纪初,不同种系小鼠间皮肤移植可以诱发移植排斥反应,对移植物的排斥反应是受体对移植细胞表面抗原的免疫应答,即供、受者组织抗原的相似程度(组织相容的程度)决定了移植物的存活。 组织相容性抗原(histocompatibility antigen):通过移植鉴定的与组织移植排斥反应有关的抗原。 主要组织相容性抗原系统(major histocompatibility antigen system, MHS):能引起较强移植排斥反应的组织细胞抗原。 主要组织相容性复合体(major histocompatibility complex, MHC):编码主要组织相容性抗原的基因群。 人类白细胞抗原(human leukocyte antigen, HLA):指人的主要组织相容性抗原系统。由于首先在人外周血白细胞表面发现,故称人类白细胞抗原。编码该抗原的基因称为HLA复合体,即人类的MHC。 H-2复合体:指小鼠的MHC,编码小鼠的主要组织相容性抗原,即H-2系统。 MHC通常指基因;MHC分子或主要组织相容性抗原指MHC基因编码的产物。对于某一动物,MHC可同时代表基因和抗原,如H-2可用于指基因和编码的分子。 不同动物的MHC的名称不同。 二、MHC的基因构成 (一)小鼠H-2复合体 定位于第17号染色体,包括K、I、S、D/L等基因。根据各基因编码分子不同分成三类:I类基因:包含K、D、L位点基因,编码I类分子的重链; Ⅱ类基因:包括I位点基因,可分为I-A和I-E亚区,编码Ⅱ类分子。Ir基因(免疫应答基因,immune response gene):位于I区,Ia抗原(I区相关抗原,I region associated antigen):Ir基因编码产物。 Ⅲ类基因:为S区基因,编码补体C4、C2、B因子及肿瘤坏死因子(TNF-α、TNF-β)等分子。 (二)人类HLA复合体 定位于第6号染色体短臂(6p21,3)。分成三类基因区: I类基因:位于HLA基因复合体远离着丝点的一端,包括经典基因HLA-B、C、A基因位点和非典型基因HLA-E、F、G位点等。Java练习题(试卷)
第八章 群体遗传学(答案)
实验6 多态性(一)
继承与多态习题
C 的封装性、继承性和多态性概念
第八章 主要组织相容性复合体
实验八 多态性