在不同类中,数据成员和函数成员一般是不同的,但有时会有部分相同。所谓的继承就是在一个已存在的类上建立一个新的类,已存在的类称为父类或者基类,新建立的类称为派生类或者子类,一个新类从已有的类那里获得其已有特性,这叫做类的继承,通过继承,一个新建子类从已有的父类那里获得父类的特性,从另一角度来说,从已有的类参数一个新的子类,称为类的派生。
派生类继承了基类的所有数据成员和函数成员,并可以对成员作必要的增加或者调整,一个基类可以派生出多个派生类,每一个派生类又可以作为基类再派生处新的派生类,因此基类和派生类是相同而言的。
上述过程是一个派生类从一个基类派生出来的,这种称为单继承。一个派生类不仅可以从一个基类派生,也可以从多个基类派生,一个派生类有两个或者多个基类的称为多重继承。
派生类的声明方式如下:
class Student1:public Student
{
public:
void display1()
{
cout<<"age:"<<age<<endl;
}
private:
int age;
string addr;
}
继承方式包括:public,private,protected,继承方式默认为private。
派生类把除了构造函数和析构函数的内容全部继承过来,虽然不能选择继承成员,但是可以对成员对象调整访问属性,也可以在派生类中重新定义一个覆盖父类中的。
在定义一个派生类使用公用继承时,基类中的访问属性为私有,则派生类中不可访问,公有为公有,保护为保护;使用私有继承时,基类访问属性为私有,派生类中不可访问,公有为私有,保护为私有,使用保护继承时,私有不可访问,公有为保护,保护为保护。下面总结成表:
派生类中访问属性 | 在派生类中 | 在派生类外 | 在下一层共用派生类中 |
公用 | 可以 | 可以 | 可以 |
保护 | 可以 | 不可以 | 可以 |
私有 | 可以 | 不可以 | 不可以 |
不可访问 | 不可以 | 不可以 | 不可以 |
派生类构造函数一般形式为:
派生类构造函数名(总参数表):基类构造函数名(参数表),子对象名(参数表)
{
派生类中新增数据成员初始化语句;
}
在多层派生的时候,不要列出每一层派生类的构造函数,只需要写出上一层派生类的构造函数即可。如果基类中没有定义构造函数或者定义了无参的构造函数,则派生类中可以不写基类构造函数。
对于多重继承,有格式:
class D:public A,private B,protected C
{
类D新增加的成员
}
对于多重派生的构造函数,有格式:
派生类构造函数名(总参数表):基类1构造函数(参数表),基类2构造函数(参数表),基数3构造函数(参数表)
{
派生类中新增数据成员初始化语句;
}
如果派生类中会保留该间接共同基类数据成员的多份同名成员,在派生类对象名后增加直接基类名,以避免产生二义性,使其唯一地标识一个成员,如c1.A::display()。
虚基类在继承间接共同基类时只保留一份成员,经过关键字声明后,当基类通过多条派生路径被一个派生类继承时,该派生类只继承该基类一次,即基类成员只保留一次。
class A
{
A(int i)
{
}
};
class B:virtual public A
{
B(int n):A(n)
{
}
};
class C:virtual public A
{
C(int n):A(n)
{
}
}
class D:public B,public C
{
D(int n):A(n),B(n),C(n)
{
}
};
在最后的派生类中不仅要负责对其直接基类进行初始化,还要负责对虚基类初始化。
只能用子类对象对其基类对象复制,而不能用基类对象对其子类对象复制,同一基类的不同派生类之间也不能复制。派生类对象可以替代基类对象向基类对象的引用进行赋值或初始化,如果函数的参数是基类对象或基类对象的引用,相应的实参可以用子类对象。派生类对象的地址可以赋给指向基类对象的指针变量。
在一个类中以另一个类的对象作为数据成员,称为类的组合。
class Teacher
{
public:
private:
int num;
string name;
char sex;
};
class BirthDate
{
public:
private:
int year;
int month;
int day;
};
class Professor:public Teacher
{
public:
private:
NirthDate birthdat;
}
类之间不是“是”的关系,而是有的关系。