面向对象程序设计2.0 继承和派生

一、温习一下之前写过的

class Date
{
private:
    int year;
    int month;
    int day;
    //数据成员,默认为私有

public:
    Date():year(2000),month(1),day(1){}//不带参数的构造函数

    Date(int year,int month,int day)//带参数的构造函数
    {
        this->year=year;
        this->month=month;
        this->day=day;
    }

    /*这里可以缺省参数
    Date(int year=2000,int month=1,int day=1)//带参数的构造函数
    {
        this->year=year;
        this->month=month;
        this->day=day;
    }*/

    Date(const Date&t)  //拷贝构造函数,浅拷贝,系统默认会有
    {
        year=t.year;
        month=t.month;
        day=t.day;
    }
    /*  
        Date data1=(2004,6,5)
        Data data2;
        data2=data1;(错误)
        Data data2=data1;(正确)
        等号需要运算符重载才可以使用。
    */

    ~Date() //析构函数
    {
        cout<<"Distract"<<endl;     //当调用析构函数的时候会输出distract。
    }
    void print()const     //普通成员函数
    {
        cout<<year<<"\t"<<month<<"\t"<<day<<endl;
    }

};

class Person
{
    string name;
    int age;
    char gender;
    Date date;
    static int count;
public:
    Person(){count++;}
    Person(string name,int age,char gender,int y,int m,int d):date(y,m,d)
    {
        this->name=name;
        this->age=age;
        this->gender=gender;
        count++;
    }
    ~Person(){count--;}
    void print()
    {
        cout<<name<<"\t"<<age<<"\t"<<gender<<"\t"<<endl;
        date.print();
        cout<<count<<endl;
    }
    static void printCount()
    {
        cout<<count<<endl;
    }

    friend ostream &operator<<(ostream &q,const Person &p);
};

int Person::count =0;
ostream &operator<<(ostream &q, const Person &p)
{
    cout<<p.name<<"\t"<<p.age<<"\t"<<p.gender<<endl;
    p.date.print();
}

二、继承的相关知识

同理,我们创建一个新的类,叫Student。

由于学生是人,不是吗喽,所以学生也应该具有Person类的属性。

为了避免复制粘贴的麻烦,我们可以这样写:

class Student:public Person
{
    int grade;
    int number;
public:
    Student(){}
    Student(string name,int age,char gender,int y,int m,int d,int grade,int number)
    {
      ……
    }

};

这样,类Student里就有了Person的数据成员成员:name、age、gender、date,也有了自己的数据成员:grade、number。

有规定说:要一定要提供基类函数的初始化,所以我们在构造函数里这样写:

class Student:public Person
{
    int grade;
    int number;
public:
    Student(){}
    Student(string name,int age,char gender,int y,int m,int d,int grade,int number):Person(name,age,gender,y,m,d)
    {
       this->grade=grade;
       this->number=number;
    }

};

先检查一下写的对不对

加一个print函数看看效果

  void print()
    {
        Person::print();
        cout<<grade<<"\t"<<number<<endl;
    }

写一下main函数

int main()
{
    Student w("XiaoMing",20,'M',2004,6,5,1,1);
    w.print();
    return 0;
}

然后看看输出结果

看输出结果:

第一行:小明、20、M是person的print函数里的

第二行:2004 6 5 是Date函数里的

第三行;1 是person的print里的那个count

第四行:1  1是Student里的print函数

然后是析构函数。

emmmmm,好像写的是对的,那就接着往下写吧。


继承后数据成员的权限:

总而言之:继承方式和基类里面的权限决定了派生类里面的权限

基类里私有的,派生类不能访问

剩下的就比较继承方式和基类的权限大小,取权限小的那个。

比如说,基类里是protected,继承方式是public,那么派生类里继承的数据成员的权限就是protected。


然后我们看一下几个函数的执行顺序。

先调用基类的构造函数

然后是派生类的构造函数

析构函数则是相反的,先是派生类再是基类。


多继承

这个实际上与单继承差不多

class Student:public Person,public School
……

虚继承

也就是菱形继承,比如说:

b、c是a的派生类,d是b、c的派生类

为了避免a的数据成员在d中有两个父本(一个来自于B,一个来自于C)

于是就提出了所谓的虚继承。

也就是在B声明的时候

class B:virtual public A

也就是在C声明的时候

class C:virtual public A

但是在声明D的时候

class D:public B.public C

三、写点啥练练手

基类Shape,

有成员函数printArea()

派生类Rectangle、Round

Rectangle类里有数据成员Width,Height

Round类里有数据成员r

能正确调用printArea()即为过关。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值