一、温习一下之前写过的
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()即为过关。