文档库 最新最全的文档下载
当前位置:文档库 › 继承与多态

继承与多态

继承与多态
继承与多态

继承与多态

一.基本概念与基础知识自测题

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 关键字只对紧随其后的基类名起作用。

如下派生: class Person

int No

身份证号

……class Student

int No

学生号

……class GStudent

int No

研究生号

……class Person int No 身份证号……

class Employee int No 工作证号……

class EGStudent

int No

在职学号

……

(a )派生关系Person 成员Student 新成员

GStudent 新成员

Person 成员Employee 新成员EGStudent 新成员Person Student Person Employee GStudent EGStudent (b )存储图

存储关系如(b),在职研究生类有两个Person 拷贝。采用虚基类后存储关系如下:

在职研究生类只有一个Person 拷贝。

8.2.5 简单叙述派生类与基类的赋值兼容规则。

答:凡是基类所能解决的问题,公有派生类都可以解决。在任何需要基类对象的地方都可以

采用虚基类后在职研究生类储存图

Student GStudent

EGStudent Person

Student 新成员 GStudent 新成员

Person Employee 新成员

Person 成员 EGStudent 新成员

Person Person Employe

用公有派生类的对象来代替,这条规则称赋值兼容规则。它包括以下情况:

1.派生类的对象可以赋值给基类的对象,这时是把派生类对象中从对应基类中继承来的成员赋值给基类对象。反过来不行,因为派生类的新成员无值可赋。

2.可以将一个派生类的对象的地址赋给其基类的指针变量,但只能通过这个指针访问派生类中由基类继承来的成员,不能访问派生类中的新成员。同样也不能反过来做。

3.派生类对象可以初始化基类的引用。引用是别名,但这个别名只能包含派生类对象中的由基类继承来的成员。

8.2.6在类中定义对象成员称为复合或嵌套,请对比复合与继承的异同之处。

答:成员对象是嵌套的概念,使用成员对象中的成员,只能直接访问(对象名加点号加成员名)公有成员。在类的成员函数中不能直接访问和处理成员对象的私有和保护成员,而要通过成员对象的接口去间接访问和处理。某些应用中,对象成员可以代替继承中的基类。

基类在派生类中只能继承一个(间接基类不在讨论之中)不能同时安排两个,否则成员名即使使用域分辨符也会发生冲突,但如果一定要用两个,只能采用成员对象。所以采用成员对象更加灵活。两者不是对立的,而是互为补充的。

8.2.7比较派生与模板各自的优点。

答:模板追求的是运行效率,而派生追求的是编程的效率。

通用性是模板库的设计出发点之一,这是由泛型算法和函数对象等手段达到的。为了运行的效率,类模板是相互独立的,即独立设计,没有使用继承的思想。对类模板的扩展是采用适配子(adapter)来完成的。应该说派生类的目标之一也是代码的复用和程序的通用性,最典型的就是MFC,派生类的优点是可以由简到繁,逐步深入,程序编制过程中可以充分利用前面的工作,一步步完成一个复杂的任务。

8.2.8是否使用了虚函数就能实现运行时的多态性?怎样才能实现运行时的多态性?

答:不是。实现动态多态性时,必须使用基类类型的指针变量或引用,使该指针指向该基类的不同派生类的对象,并通过该指针指向虚函数,才能实现动态的多态性。

8.2.9为什么析构函数总是要求说明为虚函数?

答:在基类中及其派生类中都动态分配内存空间时,必须把析构函数定义为虚函数,实现撤消对象时的多态性。根据赋值兼容规则可以用基类的指针指向派生类对象,如果由该指针撤销派生类对象,则必须将析构函数说明为虚函数,实现多态性,自动调用派生类析构函数。我们总是要求将类设计成通用的,无论其他程序员怎样调用都必须保证不出错,所以必须把析构函数定义为虚函数。

8.2.10什么是抽象类?含有纯虚函数的类是抽象类吗?

答:若定义一个类,它只能用作基类来派生出新的类,而不能用来定义对象,则称为抽象类。含有纯虚函数的类是抽象类。

8.2.11能否不提供源代码,做到用户自行把通用的软件转化为专用软件?怎样实现?

答:能不提供源代码,做到用户自行把通用的软件转化为专用软件。动态联编不一定要源代码,可以只有头文件和对象文件的.obj文件。软件开发商可在不透露其秘密的情况下发行.obj 形式的软件,然后由程序员利用继承机制,从所购得的类中派生出新类。能与软件开发商提供的类一起运行的软件也能与派生类一起运行,并能通过动态联编使用这些派生类中重定义

的虚函数。比如通用的财务软件可以转化为某公司的专用软件。

二.编程与综合练习题

8.3请用类的派生方式来组织下列动物实体与概念:动物,脊椎动物亚门,节肢动物门,

鱼纲,鸟纲,爬行纲,哺乳纲,昆虫纲,鲨鱼,青鱼,海马,鹦鹉,海鸥,喜鹊,蝙蝠,翼龙,蜻蜓,金龟,扬子鳄,袋鼠,金丝猴,虎,蜈蚣,蜘蛛,蝗虫,知了,螃蟹,虾。

解:动物派生出:脊椎动物亚门和节肢动物门。

脊椎动物亚门派生出:鱼纲,鸟纲,爬行纲,哺乳纲。

鱼纲派生出:鲨鱼,青鱼,海马。

鸟纲派生出:鹦鹉,海鸥,喜鹊。

爬行纲派生出:翼龙,金龟,扬子鳄。

哺乳纲派生出:蝙蝠,袋鼠,金丝猴,虎。

节肢动物门派生出:昆虫纲,蜈蚣(多足纲),蜘蛛(蜘形纲),螃蟹,虾(甲壳纲)。

昆虫纲派生出:蜻蜓,蝗虫,知了。

8.4定义商品类及其多层的派生类。以商品类为基类。第一层派生出服装类、家电类、车

辆类。第二层派生出衬衣类、外衣类、帽子类、鞋子类;空调类、电视类、音响类;

自行车类、轿车类、摩托车类。要求给出基本属性和派生过程中增加的属性。

解:按题意没有操作,所以只列出数据成员,也不再检验

#include

class Commodity{

double price; //价格

char name[20];//商品名

char manufacturer[20];//生产厂家

int items;//数量

};

class Clothing:public Commodity{//服装类

char texture[20];//材料质地

};

class Electric_Appliance:public Commodity{//家电类

enum {Black,White}type;//黑白家电

};

class Vehicle:public Commodity{//车辆类

int wheel_num;//车轮数量

};

class Shirt:public Clothing{//衬衣类

enum {Formal,Casual}Style;//式样:正式、休闲

};

class Garment:public Clothing{//外衣类

enum {Jacket,Coat}Style;//式样:夹克、外套

};

class Hat:public Clothing{//帽子类;

enum {Winter,Summer,Spring_Autumn}Style;//季节风格

};

class Shoes:public Clothing{//鞋子类

enum {Winter,Summer,Spring_Autumn}Style;//季节风格

};

class Air_Cindition:public Electric_Appliance{//空调

bool warm_cool; //是否冷暖

float power;//功率

};

class Television:public Electric_Appliance{//电视类

int Size; //尺寸

bool isColor;//是否彩色

};

class Acoustics:public Electric_Appliance{//音响类

int speaker_num; //喇叭数目

float power; //功率

};

class Bicycle:public Vehicle{//自行车类

int speed_grades; //调速级数

int wheel_size; //轮子大小

};

class Car:public Vehicle{//轿车类

float volume; //排气量

bool isSkylight; //是否有天窗

int box_num; //厢数

};

class Motorcycle:public Vehicle{//摩托车类

float volume; //排气量

};

void main(){

}

8.5以点(point)类为基类,重新定义矩形类和圆类。点为直角坐标点,矩形水平放置,

由左下方的顶点和长宽定义。圆由圆心和半径定义。派生类操作判断任一坐标点是在图形内,还是在图形的边缘上,还是在图形外。缺省初始化图形退化为点。要求包括拷贝构造函数。编程测试类设计是否正确。

解:

#include

#include

const double PI=3.1415926535;

class Point{

private:

double x,y;

public:

Point(){x = 0; y = 0; }

Point(double xv,double yv){x = xv;y = yv;}

Point(Point& pt){ x = pt.x; y = pt.y; }

double getx(){return x;}

double gety(){return y;}

double Area(){return 0;}

void Show(){cout<<"x="<

p1.Show();

cout<<"矩形rt3:"<<'\t';

rt3.Show();

switch(rt3.position(p1)){

case 0:cout<<"在矩形上"<

case -1:cout<<"在矩形内"<

case 1:cout<<"在矩形外"<

}

cout<<"圆cc3:"<<'\t';

cc3.Show();

switch(cc3.position(p1)){

case 0:cout<<"在圆上"<

case -1:cout<<"在圆内"<

case 1:cout<<"在圆外"<

}

cout<<"点p2:";

p2.Show();

cout<<"矩形rt3:"<<'\t';

rt3.Show();

switch(rt3.position(p2)){

case 0:cout<<"在矩形上"<

case -1:cout<<"在矩形内"<

cout<<"圆cc3:"<<'\t';

cc3.Show();

switch(cc3.position(p2)){

case 0:cout<<"在圆上"<

}

cout<<"点p3:";

p3.Show();

cout<<"矩形rt3:"<<'\t';

rt3.Show();

switch(rt3.position(p3)){

case 0:cout<<"在矩形上"<

cout<<"圆cc3:"<<'\t';

cc3.Show();

switch(cc3.position(p3)){

case 0:cout<<"在圆上"<

}

cout<<"点p4:";

p4.Show();

cout<<"矩形rt3:"<<'\t';

rt3.Show();

switch(rt3.position(p4)){

case 0:cout<<"在矩形上"<

cout<<"圆cc3:"<<'\t';

cc3.Show();

switch(cc3.position(p4)){

case 0:cout<<"在圆上"<

}

cout<<"点p5:";

p5.Show();

cout<<"矩形rt3:"<<'\t';

rt3.Show();

switch(rt3.position(p5)){

case 0:cout<<"在矩形上"<

case -1:cout<<"在矩形内"<

case 1:cout<<"在矩形外"<

}

cout<<"圆cc3:"<<'\t';

cc3.Show();

switch(cc3.position(p5)){

case 0:cout<<"在圆上"<

case -1:cout<<"在圆内"<

case 1:cout<<"在圆外"<

}

}

8.6几何形体的派生关系如下:

几何图形 geometric_shape)

矩形 rectangle 圆 circle 三角形(triangle)

三棱锥(t_pyramid)

长方体 box)圆柱 cylinder)圆锥 cone)三棱柱(t_prism)

对平面形体有长和面积,对立体有表面积和体积,对几何图形基类,周长、面积和体积应怎样计算(用什么函数)?对平面图形体积怎样计算(用什么函数)?对立体图形周长怎么计算(用什么函数)?要求实现运行时的多态性。请编程,并测试。

解:运行时的多态性要用指针

#include

#include

const double PI=3.1415926535;

class Geometric_shape{//几何图形

public:

virtual double perimeter()=0; //周长

virtual double area()=0; //面积

virtual double volume()=0; //体积

virtual void Show(){};

};

class Circle :public Geometric_shape{//圆

double radius;

public:

Circle(){radius = 0; }

Circle(double vv){radius = vv;}

double perimeter(){return 2.0*PI*radius;} //周长

double area(){return PI*radius*radius;} //面积

double volume(){return 0;} //体积

void Show(){cout<<"radius="<

};

class Rectangle:public Geometric_shape{//矩形

double width,length;

public:

Rectangle(){width=0; length=0;}//长宽

Rectangle(double wid,double len){

width = wid;

length= len;

}

Rectangle(Rectangle& rr){

width = rr.width;

length = rr.length;

}

double perimeter(){return 2.0*(width+length);} //周长

double area(){return width*length;} //面积

double volume(){return 0;} //体积

void Show(){cout<<"width="<

class Triangle:public Geometric_shape{//三角形

double a,b,c;

public:

Triangle(){a=0;b=0;c=0;}

Triangle(double v1,double v2,double v3){a = v1;b = v2;c = v3;}

double perimeter(){return a+b+c;} //周长

double area(){

double s=(a+b+c)/2.0;

return sqrt(s*(s-a)*(s-b)*(s-c));

} //面积

double volume(){return 0;} //体积

void Show(){cout<<"a="<

class Box:public Rectangle{//长方体

double height;

public:

Box(){height=0;}

Box(double wid,double len,double heg):Rectangle(wid,len){height=heg;}

double volume(){return area()*height;} //体积

};

class Cylinder:public Circle {//圆柱体

double height;

public:

Cylinder(){height=0;}

Cylinder(double vv,double heg):Circle(vv){height=heg;}

double volume(){return area()*height;} //体积

};

class Cone: public Circle {//圆锥

double height;

public:

Cone(){height=0;}

Cone(double vv,double heg):Circle(vv){height=heg;}

double volume(){return area()*height/3;} //体积

};

class T_pyramid:public Triangle{//三棱锥

double height;

public:

T_pyramid(){height=0;}

T_pyramid(double v1,double v2,double v3,double

heg):Triangle(v1,v2,v3){height=heg;}

double volume(){return area()*height/3;} //体积

};

class T_prism:public Triangle{//三棱柱

double height;

public:

T_prism(){height=0;}

T_prism(double v1,double v2,double v3,double

heg):Triangle(v1,v2,v3){height=heg;}

double volume(){return area()*height;} //体积

};

void main(){

Geometric_shape * gs;

Circle cc1(10);

Rectangle rt1(6,8);

Triangle tg1(3,4,5);

Box bx1(6,8,3);

Cylinder cl1(10,3);

Cone cn1(10,3);

T_pyramid tpy1(3,4,5,3);

T_prism tpr1(3,4,5,3);

cc1.Show();//静态

cout<<"圆周长:"<

cout<<"圆面积:"<

cout<<"圆体积:"<

gs=&rt1;//动态

gs->Show();

cout<<"矩形周长:"<perimeter()<<'\t'; cout<<"矩形面积:"<area()<<'\t';

cout<<"矩形体积:"<volume()<

gs=&tg1;//动态

gs->Show();

cout<<"三角形周长:"<perimeter()<<'\t'; cout<<"三角形面积:"<area()<<'\t';

cout<<"三角形体积:"<volume()<

gs=&bx1;//动态

gs->Show();

cout<<"长方体底周长:"<perimeter()<<'\t'; cout<<"长方体底面积:"<area()<<'\t';

cout<<"长方体体积:"<volume()<

gs=&cl1;//动态

gs->Show();

cout<<"圆柱体底周长:"<perimeter()<<'\t'; cout<<"圆柱体底面积:"<area()<<'\t';

cout<<"圆柱体体积:"<volume()<

gs=&cn1;//动态

gs->Show();

cout<<"圆锥体底周长:"<perimeter()<<'\t'; cout<<"圆锥体底面积:"<area()<<'\t';

cout<<"圆锥体体积:"<volume()<

gs=&tpy1;//动态

gs->Show();

cout<<"三棱锥底周长:"<perimeter()<<'\t'; cout<<"三棱锥底面积:"<area()<<'\t';

cout<<"三棱锥体积:"<volume()<

gs=&tpr1;//动态

gs->Show();

cout<<"三棱柱底周长:"<perimeter()<<'\t';

cout<<"三棱柱底面积:"<area()<<'\t';

cout<<"三棱柱体积:"<volume()<

}

8.7某公司雇员(employee)包括经理(manager),技术人员(technician)和销售员(salesman)。

开发部经理(developermanger),既是经理也是技术人员。销售部经理(salesmanager),既是经理也是销售员。

以employ类为虚基类派生出manager,technician和salesman类;再进一步派生出developermanager和salesmanager类。

employee类的属性包括姓名、职工号、工资级别,月薪(实发基本工资加业绩工资)。操作包括月薪计算函数(pay()),该函数要求输入请假天数,扣去应扣工资后,得出实发基本工资。

technician类派生的属性有每小时附加酬金和当月工作时数,及研究完成进度系数。

业绩工资为三者之积。也包括同名的pay()函数,工资总额为基本工资加业绩工资。

salesman类派生的属性有当月销售额和酬金提取百分比,业绩工资为两者之积。

也包括同名的pay()函数,工资总额为基本工资加业绩工资。

manager类派生属性有固定奖金额和业绩系数,业绩工资为两者之积。工资总额也为基本工资加业绩工资。

而developermanager类,pay()函数是将作为经理和作为技术人员业绩工资之和的一半作为业绩工资。

salesamanager类,pay()函数则是经理的固定奖金额的一半,加上部门总销售额与提成比例之积,这是业绩工资。

编程实现工资管理。特别注意pay()的定义和调用方法:先用同名覆盖,再用运行时多态。

解:

#include

#include

static int Grades[]={500,600,750,1000,1400,2000,2800,4000};

class employee{

protected:

char *name;//姓名

int ID;//职工号

int grade;//工资级别

double salary;//月

double base_salary;//基本月薪

double career_salary;//业绩工资

public:

employee(char* =NULL,int=0,int=0);//星号与等号间一定要有空格,否则理解成乘法~employee();

virtual void pay();//月薪计算函数

void show();

double getsalary(){return salary;}

double getbase_salary(){return base_salary;}

double getcareer_salary(){return career_salary;}

};

employee::employee(char*nn,int id,int gr){

if(nn==NULL) name=NULL;

else name=new char[strlen(nn)+1];

strcpy(name,nn);

ID = id;

grade = gr;

salary=0;//月薪

base_salary=0;//基本月薪

career_salary=0;//业绩工资

}

employee::~employee(){

if(name!=NULL) delete[]name;

}

void employee::show(){

cout<

}

void employee::pay(){

int days;

cout<<"请输入请假天数:\n";

cin>>days;

base_salary = Grades[grade]*(23 - days)/23;

career_salary = base_salary/2;//普通员工业绩工资为基本工资的一半salary = base_salary+career_salary;

}

class manager:virtual public employee{//虚基类

protected:

double prize;//固定奖金额

double factor;//业绩系数

public:

manager(char* =NULL,int=0,int=0,double=0);

void pay();

};

manager::manager(char*nn,int id,int gr,double pr):employee(nn,id,gr){ prize = pr;//固定奖金额

factor = 0;

}

void manager::pay(){

int days;

cout<<"请输入请假天数:\n";

cin>>days;

cout<<"请输入业绩系数:\n";

cin>>factor;

base_salary = Grades[grade]*(23 - days)/23;

career_salary = prize*factor*(23 - days)/23;

salary = base_salary + career_salary ;

}

class technician:virtual public employee{

protected:

double hours;//月工作时数

double perhour;//每小时附加酬金

double shfactor;//研究进度系数

public:

technician(char* =NULL,int=0,int=0,double=0);

void pay();

};

technician::technician(char*nn,int id,int gr,double phr):employee(nn,id,gr){ hours = 0;

perhour = phr;//每小时附加酬金

shfactor = 0;

}

void technician::pay(){

int days;

cout<<"请输入请假天数:\n";

cin>>days;

cout<<"请输入研究进度系数:\n";

cin>>shfactor;

hours=8*(23-days);

base_salary = Grades[grade]*(23 - days)/23;

career_salary = perhour*hours*shfactor*(23 - days)/23;

salary= base_salary + career_salary ;

}

class salesman:virtual public employee{

protected:

double amount;//销售额

double slfactor;//提成比例

public:

salesman(char* =NULL,int=0,int=0,double=0);

void pay();

};

salesman::salesman(char*nn,int id,int gr,double slfac):employee(nn,id,gr) {

amount = 0;

slfactor = slfac;//提成比例

}

void salesman::pay(){

int days;

cout<<"请输入请假天数:\n";

cin>>days;

cout<<"请输入销售额:\n";

cin>>amount;

base_salary = Grades[grade]*(23 - days)/23;

career_salary = amount*slfactor;

salary = base_salary + career_salary ;

}

class developermanager:public manager,public technician {

public:

developermanager(char* =NULL,int id=0,int gr=0,double pr=0, double phr=0);

void pay();

};

developermanager::developermanager(char*nn,int id,int gr,double pr,double phr) :manager(nn,id,gr,pr),technician(nn,id,gr,phr),employee(nn,id,gr){}

void developermanager::pay(){

int days;

cout<<"请输入请假天数:\n";

cin>>days;

cout<<"请输入业绩系数:\n";

cin>>factor;

cout<<"请输入研究进度系数:\n";

cin>>shfactor;

hours=8*(23-days);

base_salary = Grades[grade]*(23 - days)/23;//基本工资

career_salary = perhour*hours*shfactor*(23 - days)/23;//技术人员奖金

career_salary += prize*factor*(23 - days)/23;//加经理业绩工资

career_salary /=2;

salary = base_salary + career_salary ;

}

class salesmanager:public manager,public salesman{

public:

salesmanager(char* =NULL,int=0,int=0,double pr=0, double slfac=0);

void pay();

};

salesmanager::salesmanager(char*nn,int id,int gr,double pr,double slfac) :manager(nn,id,gr,pr),salesman(nn,id,gr,slfac),employee(nn,id,gr){}

void salesmanager::pay(){

int days;

cout<<"请输入请假天数:\n";

cin>>days;

cout<<"请输入业绩系数:\n";

cin>>factor;

cout<<"请输入销售额:\n";

cin>>amount;

base_salary = Grades[grade]*(23 - days)/23;//基本工资

career_salary = prize*factor*(23 - days)/23;//经理业绩工资career_salary /=2;

career_salary += amount*slfactor;//加销售业绩工资

salary = base_salary + career_salary ;

}

void main(){

employee eml1("张伟",10012,0),*emlp;

manager mag1("姚婕",20005,4,1000);

technician tec1("王茜",30047,5,10);

salesman sal1("朱明",40038,2,0.05);

developermanager dem1("沈俊",50069,6,1500,12);

salesmanager sam1("况钟",60007,3,1000,0.05);

eml1.pay();

eml1.show();

mag1.pay();

mag1.show();

tec1.pay();

tec1.show();

sal1.pay();

sal1.show();

emlp=&dem1;

emlp->pay();

emlp->show();

emlp=&sam1;

emlp->pay();

emlp->show();

}

8.8为上题添加拷贝构造函数,并测试是否正确。

解:

#include

#include

static int Grades[]={500,600,750,1000,1400,2000,2800,4000};

class employee{

protected:

char *name;//姓名

int ID;//职工号

int grade;//工资级别

double salary;//月

double base_salary;//基本月薪

double career_salary;//业绩工资

public:

employee(char* =NULL,int=0,int=0);//星号与等号间一定要有空格,否则理解成乘法employee(employee &);

~employee();

virtual void pay();//月薪计算函数

void show();

double getsalary(){return salary;}

double getbase_salary(){return base_salary;}

double getcareer_salary(){return career_salary;}

};

employee::employee(char*nn,int id,int gr){

if(nn==NULL) name=NULL;

else name=new char[strlen(nn)+1];

strcpy(name,nn);

ID = id;

grade = gr;

salary=0;//月薪

base_salary=0;//基本月薪

career_salary=0;//业绩工资

}

employee::employee(employee &emp){

if(https://www.wendangku.net/doc/1119039354.html,!=NULL){

name=new char[strlen(https://www.wendangku.net/doc/1119039354.html,)+1];

strcpy(name,https://www.wendangku.net/doc/1119039354.html,);

}

else name=NULL;

ID=emp.ID;

grade =emp.grade;

salary=emp.salary;//月薪

base_salary=emp.base_salary;//基本月薪

career_salary=emp.career_salary;//业绩工资

}

employee::~employee(){

if(name!=NULL) delete[]name;

}

void employee::show(){

cout<

}

void employee::pay(){

int days;

cout<<"请输入请假天数:\n";

cin>>days;

base_salary = Grades[grade]*(23 - days)/23;

career_salary = base_salary/2;//普通员工业绩工资为基本工资的一半

salary = base_salary+career_salary;

}

class manager:virtual public employee{//虚基类

protected:

double prize;//固定奖金额

double factor;//业绩系数

public:

manager(char* =NULL,int=0,int=0,double=0);

manager(manager&mag);

void pay();

};

manager::manager(manager&mag):employee(mag){//按赋值兼容规则mag可为employee的实参

prize=mag.prize;

factor=mag.factor;

}

manager::manager(char*nn,int id,int gr,double pr):employee(nn,id,gr){ prize = pr;//固定奖金额

factor = 0;

}

void manager::pay(){

int days;

cout<<"请输入请假天数:\n";

cin>>days;

cout<<"请输入业绩系数:\n";

cin>>factor;

base_salary = Grades[grade]*(23 - days)/23;

career_salary = prize*factor*(23 - days)/23;

salary = base_salary + career_salary ;

}

class technician:virtual public employee{

protected:

double hours;//月工作时数

double perhour;//每小时附加酬金

double shfactor;//研究进度系数

public:

technician(char* =NULL,int=0,int=0,double=0);

technician(technician &);

void pay();

};

technician::technician(technician& tech):employee(tech){

hours=tech.hours;//月工作时数

JAVA继承和多态实验报告

实验项目名称:继承和多态 (所属课程:Java语言程序设计) 院系:专业班级:姓名: 学号:实验地点:指导老师: 本实验项目成绩:教师签字:日期: 1.实验目的 (1)掌握类的继承机制。 (2)熟悉类中成员变量和方法的访问控制。 (3)熟悉方法或构造方法多态性。 2.实验内容 (1)模拟编写程序,理解类的继承、多态、继承和多态规则。 (2)独立编程,实现类的继承和多态。 3.实验作业 设计一个类Shape(图形)包含求面积和周长的area()方法和perimeter()方法以及设置颜色的方法SetColor(),并利用Java多态技术设计其子类Circle(圆形)类、Rectangle (矩形)类和Triangle(三角形)类,并分别实现相应的求面积和求周长的方法。每个类都要覆盖toString方法。 海伦公式:三角形的面积等于s(s-a)(s-b)(s-c)的开方,其中s=(a+b+c)/2 程序代码为: Class包 package Class; public class Shape { private String color = "while"; public Shape(String color){ this.color = color; } public void setColor(String color){ this.color = color; } public String getColor(){ return color;

} public double getArea(){ return 0; } public double getPerimeter(){ return 0; } public String toString(){ return"color:" + color; } } package Class; public class Circle extends Shape { private double radius; public Circle(String color,double radius) { super(color); this.radius = radius; } public void setRadius(double radius){ this.radius = radius; } public double getRadius(){ return radius; } public double getCircleArea(){ return 3.14*radius*radius; } public double getCirclePerimeter(){ return 3.14*2*radius; } public String toString(){

继承与多态习题

继承与多态习题 一.基本概念与基础知识自测题 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 关键字只对紧随其后的基类名起作用。

Java继承与多态实验报告

西安邮电大学 (计算机学院) 课内实验报告 实验名称:继承与多态 专业名称:计算机科学与技术 班级:计科1405班 学生姓名:高宏伟 学号:04141152 指导教师:刘霞林 实验日期:2016.10.13

一、实验目的 通过编程和上机实验理解Java 语言的继承和多态特性,掌握变量的隐藏、方法的覆盖、重载,掌握抽象类和接口的使用。 二、实验要求 1.编写体现类的继承性(成员变量、成员方法、成员变量隐藏)的程序。 2.编写体现类的多态性(成员方法重载)的程序。 3.编写体现类的多态性(构造方法重载)的程序。 4.编写使用接口的程序。 三、实验内容 (一)类的继承 1.创建公共类Student. (1)编写程序文件Student.java,源代码如下: public class Student { protected String name; //具有保护修饰符的成员变量 protected int number; void setData(String m,int h) //设置数据的方法 { name =m; number= h; } public void print() //输出数据的方法 { System.out.println(name+", "+number); } } (2)编译Student.java,产生类文件Student.class。 2.创建继承的类Undergraduate

(1)程序功能:通过Student 类产生子类undergraduate,其不仅具有父类的成员变量name()、number(学号),还定义了新成员变量academy(学院)、department (系)。在程序中调用父类的print 方法。 (2)编写Undergraduate 程序: class Undergraduate extends Student { 【代码1】//定义成员变量academy 【代码2】//定义成员变量department public static void main(String args[]) { 【代码3】//创建一个学生对象s 【代码4】//用父类的setData方法初始化对象s 【代码5】//对象s调用print方法 【代码6】//创建一个大学生对象u 【代码7】//调用父类的成员方法setData初始化对象u 【代码8】//设置对象u的成员变量academy 【代码9】//设置对象u的成员变量department System.out.print(https://www.wendangku.net/doc/1119039354.html,+", "+u.number+", "+u.academy+", "+u.department); } } (3)编译并运行程序 注意:公共类Student 与undergraduate 类要在同一文件夹(路径)。 (二)方法的重载 (1)程序功能:对不同的数进行排序输出。在IntSort 类中定义3 个同名的方法sort。 (2)编写Sort.java 文件,源代码如下。 import java.awt.Graphics; import java.applet.Applet; class IntSort { public String sort(int a, int b) { if (a>b) return a+""+b; else return b+""+a; } public String sort(int a, int b, int c) { int swap; if (a

实验报告(四)继承和多态 (完整代码)

福建农林大学计算机与信息学院实验报告 实验(四)继承和多态 一、实验目的和要求 1.掌握面向对象的继承关系 2.理解面向对象的多态 3.掌握方法的重写 4.掌握接口的实现 二、实验内容和原理 设计一个抽象类Shape,包括2个抽象方法,分别是计算形状的周长和面积。设计具体类Rectangle和Circle,分别表示矩形和圆,它们都是Shapes的子类。使Rectangle和Circle都实现Comparable接口(根据面积比较大小),编写一个通用的排序程序和一个通用的二分查找程序(自己写代码实现),能对这二种类型的数组进行排序并查找指定的对象。 三、实验环境 1.硬件环境: 2.软件环境:JDK1.5 四、算法描述及实验步骤 1.算法描述(可以用类图、流程图、伪代码或源程序描述) package test; import javax.swing.JOptionPane; import java.util.Scanner; public class Test { public static void main(String[] args) { System.out.println("要创建几个圆?:");

Scanner a1 = new Scanner(System.in); int a = a1.nextInt(); System.out.println("总共创建了" + a + "个圆\n请输入各个圆的半径:"); Shape[] circle = new Shape[a]; Scanner input2 = new Scanner(System.in); for (int i = 0; i < a; i++) { circle[i] = new Circle(input2.nextDouble()); } System.out.println("要创建几个矩形?:"); Scanner b2 = new Scanner(System.in); int b = b2.nextInt(); Shape[] rectangle = new Shape[b]; System.out.println("总共创建了" + b + "个矩形\n请依次输入各个矩形的长和宽:"); Scanner c3 = new Scanner(System.in); for (int i = 0; i < b; i++) { rectangle[i] = new Rectangle(c3.nextDouble(), c3.nextDouble()); } Shape.sort(circle); String str1 = ""; for (int i = 0; i < circle.length; i++) { str1 += String.valueOf(i + 1) + circle[i] + "\n"; } System.out.println("您所创建的圆按半径由小到大排序如下:\n" + str1); Shape.sort(rectangle); String str2 = ""; for (int i = 0; i < rectangle.length; i++) { str2 += String.valueOf(i + 1) + rectangle[i] + "\n"; } System.out.println("您所创建的矩形按面积由小到大排序如下:\n" + str2);

对多态性和继承的理解

C#中的继承符合下列规则: 1、继承是可传递的。如果C从B中派生,B又从A中派生,那么C不仅继承了B中声明的成员,同样也继承了A中的成员。Object 类作为所有类的基类。 2、派生类应当是对基类的扩展。派生类可以添加新的成员,但不能除去已经继承的成员的定义。 3、构造函数和析构函数不能被继承。除此以外的其它成员,不论对它们定义了怎样的访问方式,都能被继承。基类中成员的访问方式 只能决定派生类能否访问它们。 4、派生类如果定义了与继承而来的成员同名的新成员,就可以覆盖已继承的成员。但这并不因为这派生类删除了这些成员,只是不能再 访问这些成员。 5、类可以定义虚方法、虚属性以及虚索引指示器,它的派生类能够重载这些成员,从而实现类可以展示出多态性。 6、派生类只能从一个类中继承,可以通过接吕实现多重继承。 多态性 在C#中,多态性的定义是:同一操作作用于不同的类的实例,不同的类将进行不同的解释,最后产生不同的执行结果。C#支持两种类型的多态性: ●编译时的多态性 编译时的多态性是通过重载来实现的。对于非虚的成员来说,系统在编译时,根据传递的参数、返回的类型等信息决定实现何种操作。 ●运行时的多态性 运行时的多态性就是指直到系统运行时,才根据实际情况决定实现何种操

作。C#中,运行时的多态性通过虚成员实现。 编译时的多态性为我们提供了运行速度快的特点,而运行时的多态性则带来了高度灵活和抽象的特点。 2、实现多态 多态性是类为方法(这些方法以相同的名称调用)提供不同实现方式的能力。多态性允许对类的某个方法进行调用而无需考虑该方法所提供的特定实现。可以用不同的方式实现组件中的多态性: ●接口多态性。 ●继承多态性。 ●通过抽象类实现的多态性。 接口多态性 多个类可实现相同的“接口”,而单个类可以实现一个或多个接口。接口本质上是类需要如何响应的定义。接口描述类需要实现的方法、属性和事件,以及每个成员需要接收和返回的参数类型,但将这些成员的特定实现留给实现类去完成。组件编程中的一项强大技术是能够在一个对象上实现多个接口。每个接口由一小部分紧密联系的方法、属性和事件组成。通过实现接口,组件可以为要求该接口的任何其他组件提供功能,而无需考虑其中所包含的特定功能。这使后续组件的版本得以包含不同的功能而不会干扰核心功能。其他开发人员最常使用的组件功能自然是组件类本身的成员。然而,包含大量成员的组件使用起来可能比较困难。可以考虑将组件的某些功能分解出来,作为私下实现的单独接口。 根据接口来定义功能的另一个好处是,可以通过定义和实现附加接口增量地将功能添加到组件中。优点包括:

继承与多态的习题

一:选择题 1. 下面有关析构函数的说法中,不正确的是( ) A.析构函数中不可包含Return语句 B.一个类中只能有一个析构函数 C.用户可定义有参析构函数 D.析构函数在对象被撤销时,被自动调用 2.派生类不可以访问基类的( ) A.Public成员B.Private成员 C.Protected成员D.Protected internel成员 3.有关sealed修饰符,描述正确的是( ) A.密封类可以被继承 B.abstract修饰符可以和sealed修饰符一起使用 C.密封类不能实例化 D.使用sealed修饰符可保证此类不能被派生 4.若想从派生类中访问基类的成员,可以使用( ) A.this关键字B.me关键字 C.base关键字D.override关键字 5.下面有关派生类的描述中,不正确的是( ) A.派生类可以继承基类的构造函数 B.派生类可以隐藏和重载基类的成员 C.派生类不能访问基类的私有成员 D.派生类只能有一个直接基类 6.C#中,继承具有( ),即A类派生B类,B类又派生C类,则C类会继承B类中的成员和A类中的成员。 A.传递性B.多态性C.单继承D.多继承 7.下面有关静态方法的描述中,错误的是( ) A.静态方法属于类,不属于实例 B.静态方法可以直接用类名调用 C.静态方法中,可以定义非静态的局部变量 D.静态方法中,可以访问实例方法 8.下面关于运算符重载的描述中,错误的是( ) A.重载的运算符仍然保持其原来的操作数个数、优先级和结合性不变 B.可以重载双目运算符,不可以重载单目运算符 C.运算符重载函数必须是public的 D.运算符重载函数必须是static的 9.下面对派生类和基类的关系的描述中,不正确的是( ) A.派生类的方法可以和基类的方法同名 B.派生类是对基类的进一步扩充 C.派生类也可作另一个派生类的基类 D.派生类继承基类的公有、保护和私有成员 10.下面关于虚方法的描述中,正确的是() A.虚方法可以实现静态联编 B.在一个程序中,不能有同名的虚方法 C.虚方法必须是类的静态成员

通过实例理解继承与多态原理与优点

通过实例理解继承与多态原理与优点 一引子 都说面向对象的4大支柱是抽象,封装,继承与多态。但是一些初涉编程的开发人员,体会不到继承与多态的妙用,本文就试以一个经典实例来诠释继承与多态的用武之地。 二需求 1. 任务说明 我们的需求是一个影片出租的小应用,该应用会记录每个顾客的消费金额并打印出来。程序输入为:顾客租的影片及对应的租期; 程序的处理为:根据顾客租用影片时间及影片类型,计算费用;输出:打印消费单。 影片有三种类型:普通影片、儿童影片及新上映影片。 另外,模仿时下潮流,程序还提供了积分制度,为常客计算积分,积分会根据影片是否为新上映影片而不同。 2. 本实例为控制台程序,运行界面如下: 三非继承多态实现方式 根据需求,我们定义三个类,分别是movie类,Rental类(代表一条租用记录)和Customer 类(租碟顾客)

其中movie类的代码如下: 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace _https://www.wendangku.net/doc/1119039354.html,tbed 7 { 8 public enum TYPE 9 { 10 REGULAR, 11 NEW_RELEASE, 12 CHILDRENS 13 } 14 15 class Movie 16 { 17 private string _title; //movie name 18 TYPE _typeCode; //price code 19 20 public Movie() 21 { 22 _title = "unname"; 23 _typeCode = 0; 24 } 25 26 public Movie(string title, TYPE typeCode) 27 { 28 _title = title; 29 _typeCode = typeCode; 30 } 31 32 public TYPE getTypeCode() 33 { 34 return (TYPE)_typeCode; 35 } 36 37 void setTypeCode(TYPE arg) 38 { 39 _typeCode = arg; 40 } 41 42 public string getTitle() 43 {

实验报告 继承、多态与接口

实验三继承、多态与接口 一、实验目的 1.掌握Ja v a的继承机制; 2.掌握对象引用的多态方法; 3.掌握接口的特点、结构和调用; 4.掌握接口和继承的混合使用。 二、实验要求 1.编写体现类的继承性(成员变量、成员方法、成员变量隐藏) 的程序。 2.编写体现类的多态性(成员方法重载、构造方法重载)的程 序。 3.编程使用系统接口的技术和创建自定义接口的方法。 三、实验内容 (一)类的继承性练习 1.理解继承的含义 新类可从现有的类中产生,并保留现有类的成员变量和方法并可根据需要对它们加以修改。新类还可添加新的变量和方法。这种现象就称为类的继承。 当建立一个新类时,不必写出全部成员变量和成员方法。只要简单地声明这个类是从一个已定义的类继承下来的,就可以引用被继承类的全部成员。被继承的类称为父类或超类 (su pe rc la ss),这个新类称为子类。 J a va 提供了一个庞大的类库让开发人员继承和使用。设计这些类是出于公用的目的,因此,很少有某个类恰恰满足你的需要。你必须设计自己的能处理实际问题的类,如果你设计的这个类仅仅实现了继承,则和父类毫无两样。所以,通常要对子类进行扩展,即添加新的属性和方法。这使得子类要比父类大,但更具特殊性,代表着一组更具体的对象。继承的意义就在于此。 2.创建公共类S Y3_1_P 编写程序文件S Y3_1_P.ja va,源代码如下:pu bl ic c la ss SY3_1_P{ pr ote c te d St ri ng x m; //具有保护修饰符的成员变量 pr ote c te d in t xh; vo id s et da ta(S tr in g m,in t h) { //设置数据的方法 xm =m; xh = h; } pu bl i c vo id p ri nt(){//输出数据的方法 Sy st em.o ut.pr i nt ln(x m+", "+xh); } }

C++习题3(继承和多态)

习题3 一、选择题 1.在C++中,类与类之间的继承关系具有( C ) A)自反性B)对称性C)传递性D)反对称性 2.在公有继承的情况下,基类的成员(私有的除外)在派生类中的访问权限( B ) A)受限制B)保持不变C)受保护D)不受保护 3.按解释中的要求在下列程序划线处填入的正确语句是:( C ) #include class Base{ public: void fun(){cout<<"Base::fun"<fun(); 4.在保护继承的情况下,基类的成员(私有的除外)在派生类中的访问权限( C ) A)受限制B)保持不变C)受保护D)不受保护5.在哪种派生方式中,派生类可以访问基类中的protected 成员(B ) A)public和private B)public、protected和private C)protected和private D)仅protected 6.当一个派生类仅有protected继承一个基类时,基类中的所

有公有成员成为派生类的(C) A) public成员B) private成员C) protected成员 D) 友元 7.不论派生类以何种方法继承基类,都不能使用基类的(B ) A) public成员B) private成员C) protected成员D) public成员和protected成员 8下面叙述错误的是(S )。 A)基类的protected成员在派生类中仍然是protected的 B)基类的protected成员在public派生类中仍然是protected 的 C)基类的protected成员在private派生类中是private的 D)基类的protected成员不能被派生类的对象访问 9.下列说法中错误的是(S )。 A) 保护继承时基类中的public成员在派生类中仍是public 的 B)公有继承时基类中的private成员在派生类中仍是private 的 C)私有继承时基类中的public成员在派生类中是private的 D)保护继承时基类中的public成员在派生类中是protected 的 10下面叙述错误的是(C)。 A)派生类可以使用private派生 B)对基类成员的访问必须是无二义性的 C)基类成员的访问能力在派生类中维持不变 D)赋值兼容规则也适用于多继承的组合 11派生类的构造函数的成员初始化列表中,不能包含(C )。 A)基类的构造函数B)派生类中子对象的初始化 C)基类中子对象的初始化D)派生类中一般数据成员的初始化 12.下列虚基类的声明中,正确的是:( B ) A)class virtual B: public A B)class B: virtual public A

实验6类的继承与多态

(1)请编程实现如下需求:乐器(Instrument)分为:钢琴(Piano)、小提琴(Violin)、大提琴(Cello),三种乐器的弹奏play()方法各不相同。编写一个测试类InstrumentTest, 要求编写方法testPlay(Instrument in),对这三种乐器进行弹奏测试。要依据乐器的不 同,进行相应的弹奏测试,在main()方法中进行测试。 第一题: public class Instrument { public void play(){ System.out.println("演奏乐器......"); }} public class Piano extends Instrument{ public void play(){ System.out.println("弹奏钢琴......"); }} public class Violin extends Instrument{ public void play(){ System.out.println("演奏小提琴......"); }} public class TestPlay { public static void main(String[] args) { Instrument pr = new Instrument(); pr.play(); Instrument p = new Piano(); p.play(); Instrument v = new Violin(); v.play(); }} 第二题: (2)定义一个交通工具类Vehicle,包含属性(speed, name, color)和方法(start, stop, run);再定义一个飞行器子类Aircraft 继承自Vehicle 类。然后从Aircraft 类派 生两个子类:航天飞机(SpaceShuttle)和喷气式飞机(Jet)。 public abstract class Vehicle{ public int speed; public String name; public String color; public void start(){} public void stop(){} public void run(){} } public class Aircraft extends Vehicle{} public class SpaceShuttle extends Aircraft{} public class Jet extends Aircraft{}

实验2:继承、多态与面向对象程序设计(教案)

实验2:继承与多态(教案) 实验目的: 1、掌握继承、覆盖的概念 2、掌握包的概念。 3、掌握控制台应用程序、WEB应用程序的区别 4、了解类复用的概念 实验题目: 1、抽象类、及方法覆盖练习 要求:在Rectangle类中增加一个outputMessage方法,用于输出长、宽、及面积。如程序运行时Console(控制台)窗口中输出: test.java源程序: public class test { public static void main(String[] args) { Rectangle r = new Rectangle(10,20); r.calculateArea(); r.outputMessage(); } } abstract class Shape { abstract void calculateArea (); void outputMessage() { System.out.println("以下为相关输出信息:"); }; } class Rectangle extends Shape { private int height; private int width; private float area; Rectangle(int x, int y) { setWidth(x);setHeight(y); } void calculateArea() { setArea(getWidth()* getHeight());

} void setWidth(int width) { this.width = width; } int getWidth() { return width; } void setHeight(int height) { this.height = height; } int getHeight() { return height; } void setArea(float area) { this.area = area; } float getArea() { return area; } void outputMessage() { super.outputMessage(); System.out.println("长:"+this.getWidth()); System.out.println("宽:"+this.getHeight()); System.out.println("面积:"+this.getArea()); }; } 2、根据需求,完成一个简单高校工资管理信息程序 需求描述: 某高校教师分为兼职和全职教师,兼职教师的工资来源为实际课时课酬:按照职称不同,每课时课酬不同。如:教授:150元/课时;副教授100元/课时; 全职教师的工资来源为基本工资和超基本课时以外的超课时课酬(简称超课时课酬):按职称不同,每课时课酬不同。如:教授:基本工资5000元,超课时课酬为100元/课时;副教授基本工资4000元,超课时课酬为80元/课时; 每个月各系教学秘书会上报数据供人事处进行工资结算。上报数据包括:教师名、职称、实际课时数/超额课时数 参考类图设计见下图: 注意: 1)其中Ex2_Payroll是包名,Employee是抽象类,必须定义在自己的类文件中Employee.java 中。类Employee的calculateWage方法是抽象方法 2)Ex2_Payroll包中除Employee抽象类以外,还包括: 类FulltimeTeacher:是一个Public类,必须定义在自己的类文件中:FulltimeTeacher.java 类ParttimeTeacher:是一个Public类,必须定义在自己的类文件中:ParttimeTeacher.java

Java实验五继承与多态

实验五继承与多态 一、实验目的 1.掌握抽象类的声明; 2.掌握多态的执行机理; 3.掌握上转型的使用; 4.掌握构造方法的执行机理; 5.面向抽象的编程; 二、实验内容 1.假定根据学生的3门学位课程的分数决定其是否可以拿到学位,对于本科生, 如果3门课程的平均分数超过60分即表示通过,而对于研究生,则需要平均超过80分才能够通过。根据上述要求,请完成以下Java类的设计: (1)设计一个基类Student描述学生的共同特征。 (2)设计一个描述本科生的类Undergraduate,该类继承并扩展Student类。 (3)设计一个描述研究生的类Graduate,该类继承并扩展Student类。 (4)设计一个测试类StudentDemo,分别创建本科生和研究生这两个类的对象,并输出相关信息。 2.假定要为某个公司编写雇员(40个雇员)工资支付程序,这个公司有各种类型 的雇员(Employee),不同类型的雇员按不同的方式支付工资: (1)经理(Manager)——每月获得一份固定的工资 (2)销售人员(Salesman)——在基本工资的基础上每月还有销售提成。(3)一般工人(Worker)——则按他每月工作的天数计算工资。 根据上述要求试用类的继承和相关机制描述这些功能,并编写一个Java Application程序,演示这些类的用法。(提示:应设计一个雇员类(Employee)描述所有雇员的共图特性,这个类应该提供一个计算工资的抽象方法ComputeSalary( ),使得可以通过这个类计算所有雇员的工资。经理、销售人员和一般工人对应的类都应该继承这个类,并重新定义计算工资的方法,进而给出它的具体实现。(用对象数组) 三、实验报告涉及以下内容 1.继承中父子构造方法的执行关系 2.重写 3.super的应用 4.上转型 5.多态

JAVA基础 第4章继承与多态_练习题_200910

第4章继承与多态一.选择题 1、编译与运行以下两文件结果就是( D )。 //文件P1、java package MyPackage; class P1{ void afancymethod(){ System、out、println("What a fancy method"); } } //文件P2、java package YourPackage; import MyPackage、*; public class P2 extends P1{ public static void main(String argv[]){ P2 p2 = new P2(); p2、afancymethod(); } } A.两个均通过编译,P2运行时输出What a fancy method B.没一个通过编译 C.两个均通过编译,但P2运行时出错 D.P1 通过编译,但P2出现编译错误 2.下列程序运行的结果就是( A )。 package a; package b; public class D{ public static void main(String args[]) { System、out、println("^_^,今天心情不错!"); } } A.出现编译错误 B.^_^,今天心情不错! C.通过编译,运行时出错 D.以上都不对 3.Java的核心类库中哪个包,Java系统能自动引入( B )。 A.java、io B.java、lang C.java、net D.java、util 4.下列程序运行结果就是( A )。 private class Base{ Base(){ int i = 100; System、out、println(i); }

继承与多态性习题参考答案

继承与多态性习题参考答案

————————————————————————————————作者:————————————————————————————————日期:

C++程序设计语言习题及实验指导 第8章继承与多态性习题参考答案 8.3 习题 8.3.1 选择题 题号 1 2 3 4 5 6 7 8 9 10 答案 C D A D A B C B D D 题号11 12 13 14 15 16 17 18 19 20 答案 D D A C B C C C A C 8.3.2 填空题 1.(1) a、b、c、x、y、z (2) b、y (3) c、z (4) a、x (5) b、c、x、y、z (6) b、y (7) y (8) b、c、z (9) a、x (10) b、c、x、y、z (11) y (12) y (13) z (14) a、b、c、x (15) b、c、x、y、z (16) y 2.私有 3.抽象 4.虚基 5.(1) 基类(2) 对象 6.(1) 静态(2) 编译(3) 虚函数 7.(1) 2 1 (2) 0 5 8.(1) 100 200 300 30 (2) 10 100 (3) 20 200 9.(1) 5 10 (2) end. (3) 20 10 10.(1) classA classB (2) end. (3) ~classB ~classA 11.(1) 10 (2) build B (3) build C (4) release A 12.(1) class B (2) class C (3) class D (4) 5 13.(1) 5 5 (2) 20 20 14.(1) 10 (2) 10 20 15.(1) 1 (2) 3 (3) 5 (4) 100 10 16.(1) B::f() (2) B::fun() (3) A::f() (4) B::fun() 17.(1) 姓名陈涛年薪6.8万元。(2) 姓名李原(3) 姓名李原月工资4000元18.(1) 110 (2) 2220 19.(1) protected 或public (2) Base1(s1),Base2(s2) 或Base2(s2),Base1(s1) (3) Base1::str (4) test.print() 20.(1) virtual void show()=0 (2) C(int,int,int) (注:参数可有任一名称) (3) b1(y) (4) &t 8.3.3 编程题 1.求长方形的面积和长方体的表面积、体积 #include class Rectangle{ protected: float L; // 长方形的长 float W; // 长方形的宽

Java继承与多态实验报告

西安邮电大学 (计算机学院) 课内实验报告 实验名称: 继承与多态 专业名称: 计算机科学与技术 班级: 计科1405班 学生姓名: 高宏伟 学号: 指导教师: 刘霞林 实验日期: 2016、10、13 一、实验目的 通过编程与上机实验理解Java 语言的继承与多态特性,掌握变量的隐藏、方法的覆盖、重载,掌握抽象类与接口的使用。 二、实验要求 1、编写体现类的继承性(成员变量、成员方法、成员变量隐藏)的程序。 2、编写体现类的多态性(成员方法重载)的程序。 3、编写体现类的多态性(构造方法重载)的程序。 4、编写使用接口的程序。 三、实验内容 (一)类的继承 1、创建公共类Student、 (1)编写程序文件Student、java,源代码如下: public class Student { protected String name; //具有保护修饰符的成员变量

protected int number; void setData(String m,int h) //设置数据的方法 { name =m; number= h; } public void print() //输出数据的方法 { System、out、println(name+", "+number); } } (2)编译Student、java,产生类文件Student、class。 2.创建继承的类Undergraduate (1)程序功能:通过Student 类产生子类undergraduate,其不仅具有父类的成员变量 name(姓名)、number(学号),还定义了新成员变量academy(学院)、department (系)。在程序中调用父类的print 方法。 (2)编写Undergraduate 程序: class Undergraduate extends Student { 【代码1】//定义成员变量academy 【代码2】//定义成员变量department public static void main(String args[]) { 【代码3】//创建一个学生对象s 【代码4】//用父类的setData方法初始化对象s 【代码5】//对象s调用print方法 【代码6】//创建一个大学生对象u 【代码7】//调用父类的成员方法setData初始化对象u 【代码8】//设置对象u的成员变量academy 【代码9】//设置对象u的成员变量department System、out、print(u、name+", "+u、number+", "+u、academy+", "+u、department); } } (3)编译并运行程序 注意:公共类Student 与undergraduate 类要在同一文件夹(路径)内。 (二)方法的重载 (1)程序功能:对不同的数进行排序输出。在IntSort 类中定义3 个同名的方法sort。 (2)编写Sort、java 文件,源代码如下。 import java、awt、Graphics; import java、applet、Applet; class IntSort { public String sort(int a, int b) { if (a>b) return a+""+b;

05继承与多态

1.下面关于继承的描述正确的有:【选择两项】AD A在java 中只允许单一继承。// B在java 中一个类只能实现一个接口。//一个类只能实现多个接口 C在java 中一个类不能同时继承一个类和实现一个接口。//所有的类都继承object D java 的单一继承使代码更可靠。// 2.下面程序中第10行调用的方法是在第几行声明的:【选择一项】D 1 class Person { 2 public void printValue(int i, int j) {/*…*/ } 3 public void printValue(int i){/*...*/ } 4 } 5 public class Teacher extends Person { 6 public void printValue() {/*...*/ } 7 public void printValue(int i) {/*...*/} 8 public static void main(String args[]){ 9 Person t = new Teacher();//多态 10 t.printValue(10); //多态调用子类方法、父类属性 11 } 12 } A第2行 B第3行 C第6行 D第7行 3.对于下面给定的代码,下面哪些选项可以添加到程序的第11行处:【选择一项】D 1 class Person { 2 String name,department; 3 public void printValue(){ 4 System.out.println("name is "+name); 5 System.out.println("department is "+department); 6 } 7 } 8 public class Teacher extends Person { 9 int salary; 10 public void printValue(){ 11 //doing the same as in the parent method printValue() 12 System.out.println("salary is "+salary); 13 } 14 } A printValue();//递归 B this.printValue();//递归 C Person.printValue();//不是静态的

相关文档