1. 继承的基本概念
- 继承是面向对象程序设计使代码复用的最重要的手段,允许在保持原有类特性的基础上进行扩展,增加功能,产生新的类,称为派生类/子类。
- 继承是类设计层次的复用。
1.1 继承的定义
- 派生类 : 继承方式 基类
class Student : public Person
1.2 继承基类成员访问方式的变化
- 父类成员在子类中的访问权限(除过父类中的私有成员):min(原有权限,继承方式)
- 基类private成员在派生类中,无论以什么方式继承都是不可见的。
- 使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public。
类成员/继承方式 | public继承 | protected继承 | private继承 |
---|
基类的public成员 | 派生类的public成员 | 派生类的protected成员 | 派生类的private成员 |
基类的protected成员 | 派生类的protected成员 | 派生类的protected成员 | 派生类的private成员 |
基类的private成员 | 在派生类中不可见 | 在派生类中不可见 | 在派生类中不可见 |
class Person
{
public:
void Print()
{
cout << "name:" << _name << endl;
cout << "age:" << _age << endl;
}
protected:
string _name = "peter";
int _age = 18;
private:
int _id = 20180212;
};
class Student : public Person
{
public:
void PrintStu()
{
cout << _name << _age << endl;
}
int _stuid = 20;
};
2. 基类和派生类对象赋值转换
- 基类对象不能赋值给派生类对象;
- 派生类对象可以赋值给基类的对象、指针、引用;
- 切片:把派生类中父类的那部分切下来赋给子类;
- 基类指针可以通过强制类型转换赋值给派生类的指针,但必须是基类的指针是指向派生类对象时才是安全的。
void test()
{
Student s;
Person p;
p = s;
Person& rs = s;
Person* ps = &s;
Student& rs2 = s;
Student* ps2 = (Student*)ps;
Student& rp = (Student&)rs;
Student* pp = (Student*)&p;
int ret = pp->_stuid;
pp->PrintStu();
}
3. 继承中的作用域
- 在继承体系中,基类和派生类都有独立的作用域;
- 子类和父类中又同名成员时,子类成员将屏蔽父类堆同名成员的直接访问,即同名隐藏,只要函数名相同就构成同名隐藏;
- 可以在子类成员函数中,使用基类::基类成员显式访问;
class A
{
public:
void fun(int a)
{
cout << "A::fun()" << endl;
}
protected:
int _a = 1;
};
class B :public A
{
public:
void fun()
{
cout << "B::fun()" << endl;
}
void printB()
{
cout << _a << endl;
cout << A::_a << endl;
}
private:
int _a = 100;
};
void test()
{
B b;
b.printB();
b.fun();
b.A::fun(10);
}