zoukankan      html  css  js  c++  java
  • 继承

    继承是C++语言的一种重要机制,该机制自动地为一个类提供来自另一个类的操作和数据结构,这使得程序员只需在新类中定义已有类中没有的成分来建立新类。理解继承是理解面向对象程序设计的所有方面的关键,所以本章是很重要的。

    1、继承的概念:

        鸭子是鸟类的派生,鸭子是鸟类的一种,鸭子又拥有自己的特征,就是会嘎嘎叫。嘎嘎叫是区别于其他鸟类的属性。

        面向对象程序设计可以让你声明一个新类作为另一个类的派生。派生类(也称为子类继承他父类的属性和操作子类也声明了新的属性和操作,剔除了那些不适合与其用途的继承下来的操作。这样继承可让你重用父类的代码,专注于为子类写新代码。)这样使我们重新使用父类代码成为可能。

        继承可以使已存在的类不需修改地适应新应用,理解继承是理解面向对象程序设计所有方面的关键。

    2、继承的工作方式。

        

    1
    2
    3
    4
    5
    6
    class student
    {
    }
    class gradutestudent:public student
    {
    }

    gruduatestudent类继承了student的所有成员。集成的方式是在类定义中类名后跟:public student。一个研究生是一个学生。当然研究生类也有自己特有的成员。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    #include<iostream>
    #include<string>
    using namespace std;
    class Advisor//教授类
    {
    public:
        Advisor();
        ~Advisor();
     
    private:
        int numofmeeting;
    };
     
    Advisor::Advisor()
    {
     
    }
     
    Advisor::~Advisor()
    {
    }
    class Student
    {
    public:
        Student(char* pname);
        void addcourse(int hours, float score)
        {
            average = (semesterhours + average + score);//总分
            semesterhours += hours;//总修学时
            average /= semesterhours;//平均分
        }
        int gethours()
        {
            return semesterhours;
        }
        float getaverage()
        {
            return average;
        }
        void display()
        {
            cout << "name:" << name << endl;
            cout << "semehours:" << semesterhours << endl;
            cout << "averages:" << average << endl;
        }
        ~Student();
     
    private:
        char name[40];
        int semesterhours;
        float average;
    };
     
    Student::Student(char *pname="no name")
    {
        strncpy(name, pname, sizeof(name));
        average = semesterhours = 0;
    }
     
    Student::~Student()
    {
    }
    class GraduateStudent:public Student
    {
    public:
        GraduateStudent();
        int getqualifier()
        {
            return qualifierGrade;
        }
        ~GraduateStudent();
     
    private:
        Advisor advisor;
        int qualifierGrade;
    };
     
    GraduateStudent::GraduateStudent()
    {
    }
     
    GraduateStudent::~GraduateStudent()
    {
    }
    void main()
    {
        Student ds("lo see undergrade");
        GraduateStudent gs;
        ds.addcourse(32.5);
        ds.display();
        gs.addcourse(33.0);
        gs.display();
        system("pause");
        return ;
    }

        子类的实例化对象可以做父类实例化对象能做的任何事情,拥有父类的数据成员,父类的成员函数。

    3、派生类的构造:

        根据类的实现机制,派生类对象创建时,将执行其默认的构造函数。该默认构造函数会首先调用基类的默认构造函数,而基类没有默认构造函数,但正好匹配默认参数的构造函数。所以在运行结果中,gs对象的name值为no name。

        派生类可以直接访问基类的私有数据成员,甚至在构造时初始化他们,但是一般不这么做,而是通过基类的接口(成员函数)去访问他们,初始化也是通过基类的构造函数。

        类与类之间你做你的,我做我的,以接口做沟通。即使基类与子类也不例外。这正是类能够发挥其生命力的原因所在。

        在构造一个子类时,完成其基类部分的构造有积累的构造函数去做,C++类的继承机制满意的提供了这种支持。

    4、继承与组合:

        类以另一个类对象做数据成员,称为组合,继承与组合都发挥了重要作用,他们将以前设计好的类采用“拿来主义”,但是两者在使用上有所不同。graduatestudent是student类的一种,所以graduatestudent享有student的一切待遇。这种关系的差别,决定了操作上的差别。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    class vehicle
    {};
    class motor
    {};
    class car:public vehicle
    {
        public:
            motor motor;
    };
    void vehiclefn(vehicle& v)
    {};
    void motorfn(motor &m);
    void main()
    {
        car c;
        vehiclefn(c);//ok
        motorfn(c);//error
        motorfn(c.motor);//ok
    }

        汽车是车辆的子类,他继承了车辆的所有特征,而汽车具有马达,如果拥有了一辆汽车,因为汽车包含有马达,所以,同时也拥有了一个马达。

    5、多态性:

    gaduatestudent类对象gs调用student类的成员函数display(),该函数在输出时,没办法输出graduatestudent自己的数据成员qualiciergrade。因此在使用继承时,希望重载display()。

        C++允许子类重载基类的成员函数。

    6、多态的思考方式:

        若是语言不支持多态,则不能被称为面向对象的语言。

    7、多态性如何工作:

        为了指明某个成员函数具有多态性,用关键字virtual来标志其为虚函数。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    #include<iostream>
    #include<string>
    using namespace std;
    class Base
    {
    public:
        Base();
        virtual void fn()
        {
            cout << "in base class" << endl;;
        }
        ~Base();
     
    private:
     
    };
     
    Base::Base()
    {
    }
     
    Base::~Base()
    {
    }
    class Subclass:public Base
    {
    public:
        Subclass();
        virtual void fn()
        {
            cout << "in subclass " << endl;;
        }
        ~Subclass();
     
    private:
     
    };
     
    Subclass::Subclass()
    {
    }
     
    Subclass::~Subclass()
    {
    }
    void test(Base & b)
    {
        b.fn();
    }
    void main()
    {
        Base bc;
        Subclass sc;
        cout << "calling test (bc):";
        test(bc);
        cout << "calling test (sc):";
        test(sc);
        system("pause");
        return;
    }

        fn()是base类的虚函数,在test()函数中,b是基类base的传引用形参,base类对象和subclass类对象都可作为参数传递给b,所以b.fn()的调用要等到运行时,才能确认是调用基类的fn()还是子类的fn()。

        由于fn()标志为虚函数,编译看见b.fn()后,将其作为迟后联编来实现。因为多态性增加了一些数据存储和执行指令的代价,所以能不多态最好。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    #include<iostream>
    #include<string>
    using namespace std;
    class Shape
    {
    public:
        Shape(double x, double y) :xcoord(x), ycoord(y)
        {
     
        }
        virtual double Area() const return 0.0; }
        ~Shape();
     
    private:
        double xcoord;
        double ycoord;
    };
    Shape::~Shape()
    {
    }
    class Circle:public Shape
    {
    public:
        Circle(double x, double y, double r) :Shape(x, y), radius(r)
        {
     
        }
        virtual double Area()const
        {
            return 3.14*radius*radius;
        }
        ~Circle();
     
    private:
        double radius;
    };
    Circle::~Circle()
    {
    }
    class Rectangle:public Shape
    {
    public:
        Rectangle(double x1, double y1, double x2, double y2) :Shape(x1, y1), x2coord(x2), y2coord(y2){}
        double Rectangle::Area() const
        {
            return fabs((xcoord - x2coord)*(ycoord - y2coord));
        }
        ~Rectangle ();
     
    private:
        double x2coord;
        double y2coord;
    };
    Rectangle ::~Rectangle ()
    {
    }
    void fun(const Shape & sp)
    {
        cout << sp.Area() << endl;
    }
    void main()
    {
        Circle c(254);
        fun(c);
        Rectangle t(2412);
        fun(t);
        system("pause");
        return ;
    }

        多肽类让类的设计者去考虑工作的细节,而且这个细节简单到在成员函数上加一个virtual关键字。多态性使用用程序代码极大的简化,它是开启继承能力的钥匙

  • 相关阅读:
    什么是二进制补码
    第四章 VB程序的控制结构
    第三章 VB的程序设计基础
    C#學習基礎方法
    C#學習基礎繼承
    C#學習基礎變量和常量
    C#學習基礎域和屬性
    第八章 VB中ActiveX控件的使用
    写给WEB2.0的站长 不仅仅是泼冷水(转)
    常见错误和难点分析
  • 原文地址:https://www.cnblogs.com/yjds/p/8597290.html
Copyright © 2011-2022 走看看