C++初阶(封装+多态--整理的自认为很详细)
作者:互联网
继承
概念:继承机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用。
语法:
//基类(父类)
class Base
{
private:
int m1;
int m2;
}
//派生类
class Son:public Base
{
private:
int v3;
int v4;
}
继承方式
访问限定符:
- public访问
- protected访问
- private访问
1.公有继承
- 父类的公有属性和成员,到子类还是公有
- 父类的私有属性和成员,到子类还是私有,但是子类成员不可以访问这些属性和成员
- 父类的保护属性和成员,到子类还是保护
2.保护继承
- 父类的公有属性和成员,到子类是保护
- 父类的私有属性和成员,到子类还是私有,但是子类成员不能访问这些属性和成员
- 父类的保护属性和成员,到子类还是保护
3.私有继承
-
父类的公有属性和成员,到子类是私有
-
父类的私有属性和成员,到子类还是私有,但是子类成员不能访问这些属性和成员
-
父类的保护属性和成员,到子类是私有
类成员/继承方式 | public继承 | protected继承 | private继承 |
---|---|---|---|
基类的public成员 | 派生类的public成员 | 派生类的protected成员 | 派生类的private成员 |
基类的protected成员 | 派生类的protected成员 | 派生类的protected成员 | 派生类的private成员 |
基类的private成员 | 派生类中不可见 | 派生类中不可见 | 派生类中不可见 |
总结:
- 基类的private成员在派生类中都是不可见的,这里的不可见是指基类的私有成员还是被继承到了派生类对象中,但是语法上限制派生类对象不管在类里面还是类外面都不能去访问它。
- 基类成员在父类中的访问方式=min(成员在基类的访问限定符,继承方式),public>protected>private。
- 一般会把基类中不想让类外访问的成员设置为protecd成员,不让类外访问,但是让派生类可以访问。
基类和派生类对象之间的赋值转换
派生类对象会通过 “切片” 或 “切割” 的方式赋值给基类的对象、指针或引用。但是基类对象不能赋值给派生类对象。
注意:
- 从父类继承过来的成员变量,本质还是原来父类的成员变量,两个变量是一个地址
- 如果子类和父类出现两份一模一样的成员变量,要访问父类中的变量,必须使用作用域分辨符,如果不想使用作用域分辨符,对这个名字修改默认修改的就是子类的成员变量,不想使用作用域分辨符,那就在设计类的时候让两个名字不要冲突
- 记住,成员变量只要父子不同名,那么用的都是同一块地址,子类中的那个成员变量就是父类的,但是如果子类和父类成员变量重名,那么就会隐藏掉父类的成员变量,除非用::访问
class Person { public: Person(const char* name = "") :_name(name) {} void Print() { cout << "name:" << _name << " age:" << _age << endl; } protected: string _name = ""; int _age = 1; }; class Student : public Person { public: Student() :Person("xiaoming") {} void Print() { cout << "name:" << _name << " age:" << _age << " _stuid:" << _stuid << " _major:" << _major << endl; } private: int _stuid = 0;// 学号 int _major = 0;// 专业 }; int main() { Student s; // 子类对象可以赋值给父类的对象、指针和引用,反过来不行 // Student对象通过 “切片” 或 “切割” 的方式进行赋值 Person p1 = s; Person* p2 = &s; Person& p3 = s; p1.Print(); p2->Print(); p3.Print(); // 基类的指针可以通过强制类型转换赋值给派生类的指针 Student* ps = (Student*)p2; ps->Print(); return 0; }