aspx2008

记住该记住的,忘记该忘记的。改变能改变的,接受不能改变的!
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

继承和派生

Posted on 2005-05-08 14:00  極速麻醉  阅读(1056)  评论(0编辑  收藏  举报

继承和派生


继承

    继承是面向对象的程序设计的重要特色之一。面向对象的程序设计通过数据抽象,对具有共同属性和行为的事物用类进行描述。我们可以对事物按层次进行分类,把处于上层的抽象事物具有下层抽象事物的共同属性(数据成员)和行为(成员函数);面处于下层抽象事物除具有上层的抽象事物所有的属性和行为外,不具有本身所特有的特征,例如:动物可分为有脊椎动物和无脊椎动物,有脊椎动物事分为鱼类、两栖类、爬行类、鸟类和哺乳类;哺乳类动物分为猫科等,猫科动物又分为猫,老虎,狮子,豹等。

    在面向对象的程序设计中,继承类似于动物的分层关系。一个类可以从另一个类中继承特征,称为派生一个类;所派生的类称为派生类(子类);上层的被派生的类被称为基类(父类)。

派生类的定义

    定义派生类的格式如下:

class 派生类名:访问控制 基类名

{

成员表

};

    其中访问控制包括:public(公有派生)、protected(保护派生)和 private (私有派生)。

    基类中的访问权限在派生类中的继承关系如下表:

访问权限的继承

派生性质 在基类中的访问权限 在派生类中的访问权限

public

(公有派生)

public public
protected protected
private 不可访问

protected

(保护派生)

public protected
protected protected
private 不可访问

private

(私有派生)

public private
protected private
private 不可访问

例:定义一个点和一个矩形类:

class Point {

protect:

    int x,y;

public:

    Point():x(0),y(0){ }

    Point(int xx=0,int yy=0):x(xx),y(yy) { }

    int getx(){ return x;}

    int gety(){ return y;}

};

class Rectangle : public Point {

private:

    int width,high;

public:

    Rectangle(){width=0; high=0;}

    Rectangle(int w,int h){width=w; high=h;}

    int getwidth() { return width;}

    int gethigh(){ return high;}

    long area(){ return width*high; }

};

下面来看一个具体的例子:

计算球、圆柱、圆锥的表面积和体积。

分析:由于都要用到圆的半径,后两者还要用到圆的面积,所以把圆定义成基类。

 

#include <iostream.h>

#include <math.h>

#define PI 3.14159

class Circle { //圆类

protected:

    double r; //半径

public:

    Circle(double radius=0):r(radius){ }

    double area() { return PI*r*r;} //圆的表面积

     double volume() {return 0 } //计算圆的体积

};

 

class Sphere: public Circle { //球体类

public:

    Sphere(double radius=0):Circle(radius){ }

    double area() { return 4*PI*r*r; } //计算球的表面积

    double volume() { return 4*PI*pow(r,3)/3; } //计算球的体积

};

 

class Cylinder: public Circle { //圆柱类

private:

    double h; //高度

public:

    Cylinder(double radius=0,double height=0):Circle(radius){

        h=height;

    }

    double area() { return 2*PI*r*(r+h); } //计算圆柱的表面积

    double volume() { return PI*r*r*h; } //计算圆柱的体积

};

       

class Cone: public Circle { //圆锥类

private:

    double h; //高度

public:

    Cone(double radius=0,double height=0):Circle(radius){

        h=height;

    }

    double area() { //计算圆锥的表面积

        double he=sqrt(h*h+r*r);

        return *PI*r*(r+he); }

    double volume() { return PI*r*r*h/3; } //计算圆锥的体积

};

       

void main()

{

Circle r1(2);

Sphere r2(2);

Cylinder r3(2,3);

Cone r4(2,3);

cout <<"Circle:"<<r1.area()<<" "<<r1.volume()<<endl;

cout <<"sphere:"<<r2.area()<<" "<<r2.volume()<<endl;

cout <<"Cylinder:"<<r3.area()<<" "<<r3.volume()<<endl;

cout <<"Cone:"<<r1.area()<<" "<<r1.volume()<<endl;

运行结果:

Circle:12.5664 0

sphere:50.2655 33.5103

Cylinder:62.8319 37.6991

Cone:35.2207 12.5664

 

构造函数、析构函数和继承的关系

    利用派生类定义对象时,先调用基类的构造函数,然后才派生类的构造函数;析构函数以相反的顺序被调用。如:

#include <iostream.h>

class AX {

  int x;

public:

    AX(int xx=0):x(xx){

        cout <<"AX constructor."<<endl;

    }

    ~AX() { cout<<"AX destructor."<<endl;}

    void output(){ cout <<x<<" ";}

};

class BX : public AX {

  int y;

  AX z;

public:

  BX(int xx=0,int yy=0):AX(xx),y(yy),z(xx+yy)

    {

        cout<<"BX constructor."<<endl;

    }

    ~BX() { cout <<"BX destructor."<<endl;}

    }

    void output()

      {

        AX::output;

        cout<<" "<<y<<" " <<z.get()<<endl;

    }

};

void main()

{

    BX a(5),b(10,20);

    a.output();

    b.output();

}

程序的运行结果为:

AX constructor.

AX constructor.

BX constructor.

AX constructor.

AX constructor.

BX constructor.

5 0 5

10 20 30

BX destructor.

AX destructor.

AX destructor.

BX destructor.

AX destructor.

AX destructor.