继承的基本概念
一.共性与个性
•共性表达了不同类型事物之间共有的属性和行为
•个性则着意刻画每种类型事物特有的属性和行为
二.超集与子集
•超集体现了基于共性的一般
•子集体现了针对个性的特殊
三.基类与子类
•基类表示超集,体现共性,描述共有的属性和行为
•子类表示子集,体现个性,描述特有的属性和行为
四.继承与派生
•子类继承自基类
•基类派生出子类
继承语法
一.继承表
•一个子类可以同时从零到多个基类继承
•子类从每一个基类继承的继承方式可以相同也可以不同
–class 子类 : 继承方式1 基类1, 继承方式2 基类2, …
{ … };
二.继承方式
•公有继承
–public
–基类的特性将通过子类向外扩散
•保护继承
–protected
–基类的特性仅在继承链的范围内扩散
•私有继承
–private
–基类的特性仅为子类所有,不向任何方面扩散
公有继承的基本特点
皆然性
一.逻辑结构
•子类对象任何时候都可以被当做其基类类型的对象
•子类的逻辑空间小于基类
•子类对象 IS A 基类对象
二.物理结构
•基类的子类对象是其基类子对象的父对象
•子类的物理空间大于基类
•子类对象中的基类子对象与通常意义上的基类对象并没有本质性的区别
向上和向下造型
一.从子类到基类
•子类类型的指针或引用总可以被隐式地转换为其基类类型的指针或引用
•这种操作性缩小的类型转换,在编译器看来是安全的
二.从基类到子类
•基类类型的指针或引用不可以被隐式地转换为其子类类型的指针或引用
•这种操作性扩大的类型转换,在编译器看来是危险的
三.类型安全性
•编译器对类型安全所做的检测,仅仅基于指针或引用本身的数据类型,而与其目标对象的实际类型无关
–Student student (…);
Human* phuman = &student;
Student* pstudent = phuman; // 错误
Human& rhuman = student;
Student& rstudent = rhuman; // 错误
四.类型一致性
•基类指针或引用实际目标对象的类型,究竟是否与需要转换的指针或引用的目的类型一致,完全由程序员自己判断
•静态类型转换典型应用:基类指针/引用->子类指针/引用
–Student student (…);
Human* phuman = &student;
Student* pstudent = static_cast<Student*> (phuman);
Human& rhuman = student;
Student& rstudent = static_cast<Student&> (rhuman);
子类继承基类成员
一.基类的公有、保护和私有成员
•在子类中或通过子类,可以直接访问基类的所有公有和保护成员,就如同它们是在子类中声明的一样
–Student student (“张飞”, 25);
s tudent.eat (“饺子”);
student.sleep (6);
•基类的私有成员在子类中虽然存在却不可见,故无法直接访问
–string const& Human::name (void) const
{
return m_name;
}
–void Student::learn (string const& course) const
{
cout << m_name << "学" << course << endl; // 错误
cout << name () << "学" << course << endl;
}
子类隐藏基类成员
一.子类的名字隐藏
•尽管基类的公有和保护成员在子类中直接可见,但仍然可以在子类中重新定义这些名字,子类中的名字会隐藏所有基类中的同名定义
–class Human
{
void eat (string const& food) { ... }
};
–class Student : public Human
{
int eat;
};
–Student student ("张飞", 25);
student.eat ("饺子"); // 错误
二.作用域限定操作符
•如果需要在子类中或通过子类访问一个在基类中定义却为子类所隐藏的名字,可以借助作用域限定操作符“::”实现
–class Human
{
void eat (string const& food) { ... }
};
–class Student : public Human
{
int eat;
};
–Student student ("张飞", 25);
student.Human::eat ("饺子");
继承方式和访问控制符
一.访控限定符与访控属性
•访控限定符规定了一个类的特定成员,是否具有被从类的内部、类的子类,以及类的外部进行访问的能力
二.继承方式的影响范围
•基类中的公有、保护和私有成员,在其公有、保护和私有子类中的访问控制属性,会因继承方式而异
三.继承方式的作用场合
•当通过子类访问其所继承的基类成员时,需要考虑继承方式对访问控制属性的影响