实验六 继承与虚函数
- 格式:doc
- 大小:300.00 KB
- 文档页数:10
实验6类的继承与多态
实验6 类的继承与多态
实验目的及要求:
1)掌握继承、多态和向上转型的概念与实现方法;
2)掌握成员变量的隐藏和方法重写;
3)掌握关键字super的使用。
实验类型:设计型
实验内容:
(1)请编程实现如下需求:乐器(Instrument)分为:钢琴(Piano)、小提琴(Violin)、大提琴(Cello),三种乐器的弹奏play()方法各不相同。
编写一个测试类InstrumentTest,要求编写方法testPlay(Instrument in),对这三种乐器进行弹奏测试。
要依据乐器的不同,进行相应的弹奏测试,在main()方法中进行测试。
(2)定义Mother类及其属性(身高、体重、年龄)和方法(工作、做家务);定义Daughter类继承Mother类,并增加一些属性(爱好)和方法(看动画片)。
定义一个类UseExtends,在该类的main方法中创建一个名为daughter的对象,使用Mother类和Daughter类的属性和方法进行测试。
(3)定义一个交通工具类Vehicle,包含属性(speed, name, color)和方法(start, stop, run);再定义一个飞行器子类Aircraft继承自Vehicle类。
然后从Aircraft类派生两个子类:航天飞机(SpaceShuttle)和喷气式飞机(Jet)。
实验报告要求:每个程序写出设计思路、主要代码、调试过程中遇到的问题及解决方案。
虚函数的继承(中英文实用版)Title: Inheritance of Virtual Functions标题:虚函数的继承In object-oriented programming, inheritance is a way to create a new class based on an existing class.This new class inherits the properties and behaviors of the existing class, which can then be extended or modified as needed.One of the key features of inheritance is the ability to override virtual functions, allowing derived classes to provide their own implementation of a function that is already defined in the base class.在面向对象编程中,继承是一种基于现有类创建新类的方法。
这个新类继承了现有类的属性和行为,然后可以根据需要进行扩展或修改。
继承的一个关键特性是能够重写虚函数,允许派生类提供对已在基类中定义的函数的自定义实现。
When a virtual function is declared in a base class, it can be overridden in any derived class.This allows for polymorphic behavior, where a pointer or reference to the base class can be used to call the appropriate derived class function.The decision of which function to call is made at runtime, based on the actual type of the object.当在基类中声明虚函数时,它可以在任何派生类中被重写。
实验6 多态性与虚函数一.实验目的1.了解多态的概念;2.了解静态联编和动态联编的概念;3.掌握动态联编的条件;4.了解虚函数的用途及使用方法。
二源程序#include<iostream>using namespace std;class Shape{public:virtual double area()const=0;virtual void display()=0;};class TwoDimShape:public Shape{};class ThreeDimShape:public Shape{};class Circle:public TwoDimShape{public:Circle(double r){R=r;}double area()const{return 3.14*3.14*R;}void display(){cout<<"圆的面积为:"<<area()<<endl;}private:double R;};class Cube:public ThreeDimShape{public:Cube(double l){L=l;}double area()const{return 6*L*L;}void display(){cout<<"立方体的表面积为:"<<area()<<endl;} private:double L;};int main(){int i;Circle Ci1(5.2);Cube Cu1(3.3);Shape *S1[2]={&Ci1,&Cu1};for(i=0;i<2;i++){S1[i]->area();S1[i]->display();}return 0;}三.编程思想圆和立方体不属于同一类,这两类的参数不同计算方法不同,但是所求的都是面积输出的也都是面积这一个相同的成员函数。
实验六继承和重载(设计性4学时)1、实验目的与要求:掌握类的继承(方法和属性)1 类的继承性新类可从现有的类中产生,并保留现有类的成员变量和方法并可根据需要对它们加以修改。
新类还可添加新的变量和方法。
这种现象就称为类的继承。
当建立一个新类时,不必写出全部成员变量和成员方法。
只要简单地声明这个类是从一个已定义的类继承下来的,就可以引用被继承类的全部成员。
被继承的类称为父类或超类(superclass),这个新类称为子类。
Java 提供了一个庞大的类库让开发人员继承和使用。
设计这些类是出于公用的目的,因此,很少有某个类恰恰满足你的需要。
你必须设计自己的能处理实际问题的类,如果你设计的这个类仅仅实现了继承,则和父类毫无两样。
所以,通常要对子类进行扩展,即添加新的属性和方法。
这使得子类要比父类大,但更具特殊性,代表着一组更具体的对象。
继承的意义就在于此。
1.1创建将被继承的类(1) 程序源代码如下。
public class EXP3_7{protected String xm; //具有保护修饰符的成员变量protected int xh;void setdata(String m,int h) //设置数据的方法{xm =m;xh = h;}public void print() //输出数据的方法{System.out.println(xm+", "+xh);}}(2) 编译源程序。
1.2创建将被继承的类(1) 程序功能:通过EXP3_7类产生子类EXP3_8,其不仅具有父类的成员变量xm(姓名)、xh(学号),还定义了新成员变量xy(学院)、xi(系)。
在程序中调用了父类的print 方法,同时可以看出子类也具有该方法。
(2) 程序源代码如下。
class EXP3_8 extends EXP3_7{protected String xy;protected String xi;public static void main(String args[]){EXP3_7 p1 = new EXP3_7();p1.setdata("李四",12321) ;p1.print();EXP3_8 s1 = new EXP3_8() ;s1.setdata("张三",12345); //调用父类的成员方法s1.xy="成都信息工程学院"; //访问本类的成员变量s1.xi="计算机系"; //访问本类的成员变量s1.print();System.out.print(s1.xm+", "+s1.xy+", "+s1.xi);}}2 定义mypoint类,其中域为x,y和无参构造函数(屏幕输出“调用point类的无参构造方法”),定义一个含2个参数的构造函数初始化域;定义方法设置坐标,定义方法得到坐标,定义toString方法返回点坐标的字符串显示。
实验六纯虚函数与抽象类《C++程序设计》实验报告准考证号012610500632题目:纯虚函数与抽象类姓名李永伟日期2011-5-28实验环境:Visual C++ 6.0实验内容与完成情况实验目的:1,掌握抽象类定义的一般格式2,掌握抽象类的作用,及纯虚函数的定义形式,抽象类的指针在程序中的作用实验内容:1,设计多个类,并设定一个类为抽象基类,其余类在此类基础上派生,实现相关功能2,完成抽象类的定义在抽象类的基础上派生出三到四个类,并给出派生类的定义形式定义相关构造函数、析构函数在抽象类和个派生类中定义相关虚函数,并在派生类中给出函数函数体设计相关函数实现抽象类的指针的作用3,设计main函数创建多个派生类对象,调用相关函数实现数据计算功能并输出结果源程序代码:#include <iostream>#include <cmath>using namespace std;const double PI=3.14;class shape{public:virtual double area()=0;virtual ~shape(){cout<<"析构shape"<<endl;}};class square: public shape{double h;public:square(double i){ h=i; cout<<"构造square:"<<endl;cout<<"边长="<<h<<endl;}double area(){return h*h;}virtual ~square(){ cout<<"析构square\t边长="<<h<<endl;}};class circle:public shape{double r;public:circle(double a){ r=a; cout<<"构造circle:"<<endl;cout<<"半径="<<r<<endl;}double area(){return r*r*PI;}virtual ~circle(){ cout<<"析构circle\t半径="<<r<<endl;} };class rectangle:public shape{double w;double h;public:rectangle(double a,double b){ w=b; h=b; cout<<"构造rectangle:"<<endl;cout<<"宽="<< w<<endl;cout<<"高="<<h<<endl;}double area(){return h*w;}virtual ~rectangle(){ cout<<"析构rectangle:"<<endl;cout<<"宽="<<w<<endl;cout<<"高= "<<h<<endl;}};double total(shape *s[],int n){ double sum=0;for(int i=0;i<n;i++)sum=sum+s[i]->area();return sum;}void main(){shape *p[4];p[0]=new square(10);p[1]=new circle(6);p[2]=new rectangle(6,8);p[3]=new rectangle(7,5);for(int i=0;i<4;i++)cout<<"p["<<i<<"]所指对象面积="<<p[i]->area()<<endl;cout<<"总面积:"<<total(p,3)<<endl;delete p[0];delete p[1];delete p[2];delete p[3];}运行结果截图:出现的问题解决方案(列出遇到的问题和解决办法,列出未解决的问题)。
序号实验6多态性与虚函数[实验目的] ----------------------1、了解多态性的概念;2、了解虚函数的用途及使用方法;3、了解纯虚函数和抽象类的概念和用法。
[实验要求]给出以下各实验内容的源程序代码,并把编译、运行过程中出现的问题以及解决方法填入实验报告中,按时上交。
[实验学时]2学时。
[实验内容]1、写一个程序,定义抽象基类Shape由它派生出3个派生类:Circle(圆形)、Square正方形)、Rectangle矩形)。
利用指针、虚函数printArea()分别输出以上三者的面积,3个图形的数据在定义对象时给定。
[源程序]#in clude<iostream>using n amespace std;class Shape{public:virtual float area()c on st=0;virtual void display()c on st=0;};class Circle:public Shape{public:Circle(double a):r(a){}virtual float area()co nst{return 3.14*r*r;}virtual void display()c onst{cout«"圆面积"<<area()<<e ndl;}private:double r;};class Recta ngle:public Shape{public:Rectangle(double a,double b):l(a),w(b){} virtual float area()c on st{return l*w;} virtual void display()c onst{cout«"矩形面积"<<area()<<endl;}private:double l;double w;};class Square:public Shape{public:Square(double a):a1(a){}virtual float area()c on st{return a1*a1;} virtual void display()c onst{cout«"正方形面积"<<area()<<endl;}private:double a1;};int mai n(){Circle c1(5);Recta ngle r1(5,8);Square s1(2.5);Shape *p[3]={&c1,&r1,&s1};int i;double m=0.0;for (i=0;i<3;i++)p[i]->display(); m=m+p[i]->area();{coutvv"总面积:"vvmvve ndl;2、定义Point(点)类,由Point类派生出Circle(圆)类,再由Circle类派生出Cylinder(圆柱体)类。
单继承多继承虚继承条件下虚函数表的结构在面向对象编程中,继承是一种重要的概念,它允许一个类继承另一个类的属性和方法。
在C++中,继承机制的实现依赖于虚函数表(virtual function table),它是一个由编译器在编译时生成的数据结构。
虚函数表是用来解决多态性的问题,它存储了每个类的虚函数的地址,以便在运行时动态地调用适当的函数。
在单继承、多继承和虚继承条件下,虚函数表的结构略有不同。
下面将对这三种情况的虚函数表结构进行详细介绍。
1.单继承情况下的虚函数表结构:在单继承中,一个派生类只继承自一个基类。
此时,派生类的虚函数表会包含基类的虚函数的地址,并在派生类需要重写基类的虚函数时,将其重新指向派生类的重写函数的地址。
虚函数表通常由两部分组成:- 类的类型信息(type information):用来确定对象类型,并进行类型转换。
- 虚函数指针(virtual function pointer):指向虚函数表的地址。
虚函数表的结构如下所示:从图中可以看出,虚函数表的每个条目是一个指向虚函数的指针,派生类的虚函数表中包含了基类的虚函数指针和自己的虚函数指针。
派生类重写基类虚函数的地址存储在自己的虚函数指针中,当通过基类指针或引用调用虚函数时,会根据虚函数表找到派生类的虚函数地址进行调用。
2.多继承情况下的虚函数表结构:在多继承中,一个派生类可以继承自多个基类。
由于存在多个继承关系,基类的虚函数表需要在派生类的虚函数表中进行合并。
此时,派生类的虚函数表会包含所有基类虚函数的地址,并按照继承顺序排列,以确保正确的调用。
虚函数表的结构如下所示:3.虚继承情况下的虚函数表结构:虚继承是多重继承的一种特殊形式,在使用虚继承时,对象中只包含一个基类的实例,并且所有共享该基类的派生类都共享这个实例。
虚继承的目的是为了解决菱形继承问题。
虚函数表的结构如下所示:在虚继承中,派生类的虚函数表中存储了额外的信息来处理虚基类的访问。
课前讲解—类的继承与派生一、继承原理这里举一个继承的例子,定义两个类Point类,代表一个点;Rectangle类,代表一个矩形。
这里Point类(x,y)代表一个点的坐标,把它作为父类;Rectangle类,把它作为Point类的子类。
为啥这样考虑呢?因为一个点的位置决定了以后,就可以以这个点作为矩形的左上角坐标,然后再加上矩形的宽度,高度两个分量值,就可以直接构成一个矩形了。
我们可以看到,左边是Point类包含的所有属性和方法;右边则是Rectangle类包含的所有属性和方法,它的一部分属性和方法是从父类继承下来的。
任何一个矩形对象,都必须需要知道左上角的坐标位置(x,y)和其宽度w,高度h才能知道这是一个怎样的矩形。
因此每当我们用语句创建一个矩形对象的时候,需要调用initRectangle函数做矩形的初始化工作,要为这个函数传入四个参数:所传入的参数需要赋给对象的x,y,w,h分量。
由于在Rectangle类中只定义了宽度w,高度h两个属性,因此x,y的初始化工作它并不能直接完成,此时,就需要调用父类(Point类)里面的initPoint(x,y)函数来完成x,y分量的初始化,等父类的初始化工作完成后,然后再回到子类(Rectangle类)中完成w,h分量的初始化。
总结:Point类是父类,派生出Rectangle子类。
父类中定义的属性x,y被子类继承,子类中则增加了新的属性w,h。
二、派生类的构造函数和析构函数上述程序不是太好,如果引入构造函数和析构函数的概念,把上述的init函数改成构造函数,则代码会更好一些:经过上述定义后,每当创建Rectangle对象时,系统就会分配一块内存给这个对象:总共需要4个int空间,这四个数据成员都需要正确的赋予数值,才能定义一个有意义的矩形。
其中w,h两个属性是Rectangle对象可以直接访问的,而x,y两个属性继承自Point,而且是private,因此在Rectangle对象中不能直接访问这两个属性,只能通过间接调用getX(),getY()函数获取 x,y属性的值。
程序设计二(面向对象)_实训13_虚函数虚函数是面向对象程序设计中的一个重要概念,它在继承和多态的实现中起着关键的作用。
本文将介绍虚函数的概念、作用、使用方法以及一些注意事项。
一、什么是虚函数在面向对象的程序设计中,虚函数是一种特殊的成员函数,它可以在基类中声明为虚函数,并在派生类中进行重写。
通过使用虚函数,我们可以实现多态性,即同一个函数在不同的对象上表现出不同的行为。
二、虚函数的作用虚函数的主要作用是实现动态绑定。
在程序运行时,根据对象的实际类型来确定调用哪个函数。
这使得我们可以通过基类指针或引用来调用派生类的函数,实现了对派生类对象的统一操作。
三、虚函数的使用方法1. 在基类中声明虚函数:在基类中将需要在派生类中重写的函数声明为虚函数。
例如,我们有一个基类Animal,其中有一个虚函数makeSound(),表示动物发出声音。
2. 在派生类中重写虚函数:派生类继承基类后,可以重写基类中的虚函数,并根据实际需求修改函数的实现。
例如,我们有一个派生类Dog,它重写了基类中的makeSound()函数,表示狗的叫声。
3. 使用基类指针或引用调用虚函数:在程序中,我们可以使用基类的指针或引用来调用派生类中重写的虚函数,实现对派生类对象的统一操作。
例如,我们可以使用Animal*指针指向Dog对象,并通过该指针调用makeSound()函数,即使实际对象是Dog类型,也能正确调用Dog类中的makeSound()函数。
四、虚函数的注意事项1. 虚函数必须是非静态成员函数。
虚函数与对象的状态有关,因此必须是非静态成员函数。
2. 虚函数可以被派生类重写,但不能被派生类隐藏。
派生类重写虚函数时,函数的签名必须与基类中的虚函数相同,即函数名、参数列表和返回类型都要相同。
否则,派生类中的函数将隐藏基类中的虚函数,而不是重写。
3. 构造函数和析构函数不能是虚函数。
构造函数和析构函数在对象的创建和销毁过程中起着重要作用,因此不能声明为虚函数。