前言:距离上一次学习类的基本知识已经过了很长时间,可以到前面的博客去复习一下基本的知识,这一节将重新开始一篇博客,就是类的继承,这一节工作量巨大,是难点,因为不像java中一个子类只能继承一个父类,c++中可以有多个父类,所以逻辑上会难理解。不要紧,我们一点点啃它
一个简单的基类(父类)
我们首先写一个简单的父类:tabletennisplayer.h
注意:我在前面讲到过书写类的标准写法,所以为了规范我尽量把要用的this指针还有修饰关键词都加上
#ifndef TABLETENNISPLAYER_H
#define TABLETENNISPLAYER_H
#include <iostream>
#include <string>
using namespace std;
class tabletennisplayer
{
private:
string firstname; //ming
string lastname; //xing
bool hasTable;
public:
tabletennisplayer();
tabletennisplayer(const string fn , const string ln , bool ht);
void name() const;
bool HasTable() const;
void ResetTable(bool v) ;
};
#endif // TABLETENNISPLAYER_H
tabletennisplayer.cpp
#include "tabletennisplayer.h"
tabletennisplayer::tabletennisplayer()
{
firstname = "none";
lastname = "none";
hasTable = false;
}
tabletennisplayer::tabletennisplayer(const string fn , const string ln , bool ht)
{
firstname = fn;
lastname = ln;
hasTable = ht;
}
void tabletennisplayer::name() const
{
cout << this->lastname << " " << this->firstname<< endl;
}
bool tabletennisplayer::HasTable() const
{
return this->hasTable;
}
void tabletennisplayer::ResetTable(bool v)
{
this->hasTable = v;
}
main.cpp
#include <iostream>
#include <tabletennisplayer.h>
int main()
{
tabletennisplayer player1("xu","zoxu",true);
tabletennisplayer player2("shuang","zoxu",false);
player1.name();
return 0;
}
派生一个类
我们公有派生一个子类,名字叫计分运动员(ratedplayer),负责记录比分,当然它属于一种tabletennisplayer。使用公有派生,基类的公有成员成为子类的公有成员,基类的私有部分也会成为子类的一部分,但是只能通过基类的共有和保护方法访问
所以,子类的特征:
1、存储了父类的数据成员
2、子类对象可以使用基类的方法
但是,子类需要添加自己的东西:
1.自己的构造函数(包括默认的和含参数的构造函数),虽然继承了父类的构造函数,但是继承的父类的构造函数另有其用。后面会说。
2.自己的数据成员和方法
因为子类包含了父类的所有数据成员,所以子类的构造函数应该也要初始化父类的数据成员,但是初始化父类的数据成员时要用到父类的构造函数,具体是:
比如子类的默认构造为:st1();
父类类的默认构造为:st0();
,则子类的默认构造函数应写成:
st1():st0() //这表示在执行子类的默认构造函数前会先执行父类类的默认构造
{
.............
}
注意:如果需要用到父类的含参构造,需要在子类的含参构造的参数中加入父类需要的参数,这样在声明子类对象时就要指定所有数据成员(子类的+父类的)的值,只不过子类的含参构造应该写成:
st1(int a, int b ,int c):st0(b,c)
{
.............
}
但是注意:上面的仅仅是定义,而在头文件的声明中写法不一样,因为声明中不能出现初始化列表,所以声明中要写成:
st1();
st1(int a, int b ,int c ) ;//也就是最基本的构造函数的声明的写法,后面写定义时只需加上初始化列表即可
下面附上子类的代码,注意其中的细节:
ratedplayer.h
#ifndef RATEDPLAYER_H
#define RATEDPLAYER_H
#include <iostream>
#include <string>
#include <tabletennisplayer.h> //注意这里要包含父类的头文件
using namespace std;
class ratedplayer : public tabletennisplayer
{
private:
int rating;
public:
ratedplayer(); //子类的默认构造
ratedplayer(int r, string fn, string ln, bool ht); //子类的含参数构造,注意参数应包含所有的数据成员(自己的和继承的)
int Rating() const;
void ResetRating(int r);
};
#endif // RATEDPLAYER_H
ratedplayer.cpp
#include "ratedplayer.h"
ratedplayer::ratedplayer() : tabletennisplayer() //只需把父类的默认构造放在初始化列表中
{
rating = 0;
}
ratedplayer::ratedplayer(int r, string fn, string ln, bool ht):tabletennisplayer(fn,ln,ht) //只需把父类的含参数构造放在初始化列表中
{
rating = r;
}
int ratedplayer::Rating() const
{
return rating;
}
void ratedplayer::ResetRating(int r)
{
rating = r;
}