关于“C++为什么要有继承?什么是继承?”的探讨
c++为什么要有继承
我们都知道很多类都有自己的数据成员以及函数,在编写程序时,会有很多类的拥有相同的数据成员和函数,为了节省时间以及代码量,我们把这些公共的数据和函数封装成一个类,后面的类只要继承这个类即可。
什么是继承
继承是面向对象复用的重要手段。继承是类型之间的关系建模,共享公有的东西,实现各自本质不同的东西。当创建一个类时,您不需要重新编写新的数据成员和成员函数,只需指定新建的类继承了一个已有的类的成员即可。这个已有的类称为基类,新建的类称为派生类。
例如:
1.继承方式和访问限定符的关系
继承的访问限定符有:
public / protected /private
三种继承关系下基类成员的在派生类的访问关系变化
基类的私有成员在派生类中不能被访问,如果一些基类成员不想被基类帝乡访问,但需要在派生类中访问,就定义为保护成员,可以看出保护成员限定符是因继承才出现的。 public继承是一个接口继承,保持is-a原则,每个父类可用的成员对子类也可用,因为每个子类对象也都是一个父类对象。 protected/private继承是一个实现继承,基类的部分成员并未完全成为子类接口的一部分,是has-a的关系原则,所以非特殊情况下不会使用这两种继承关系,在绝大多数的场景下使用的都是公有继承。 不管是哪种继承方式,在派生类内部都可以访问基类的公共成员和保护成员,但基类的私有成员存在但是不能访问。 使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public,不过最好显示的写出继承方式。 在实际运用中一般使用public继承,极少场景下使用protected/private继承。
继承与转换(public继承):
子类对象可以赋值给父类对象(切割/切片)
父类对象不能赋值给子类对象。
父类的指针或引用可以只想子类对象。 子类对象的指针或引用不能指向父类对象
class person { public: void fun() { } protected: string _name; }; class teacher:public person { public: int _age; }; int main() { person p; teacher t; p = t; //子类对象可以赋值给父类对象。 //t=p;不允许 person *p1 = &t; //父类的指针或引用可以指向子类对象 person &q1 = t; teacher *p2 = (teacher*)&p; //子类的引用或指针不能指向父类对象,(可以强转类型之后完成) teacher& q2 = (teacher&)p; }
在继承体系中基类和派生类都有独立的作用域。
隐藏(重定义):子类和父类中有同名成员,子类成员将屏蔽父类对成员的直接访问(在子类成员函数中,可以使用 基类::基类成员 访问)
派生了默认成员函数
在继承关系里面,在派生类中如果没有显示定义六个默认成员函数,编译则会默认合成这六个成员函数。
当基类构造函数需要外部传递参数才能进行初始化时,派生类必须显式定义构造函数,为基类传递参数;基类如果不需要传递或者可以不传递参数,派生类可以不用显式定义构造函数。
lass person { public: person(const char* name) //基类构造函数 :_name(name) {} person(const person& p) //基类拷贝构造 :_name(p._name) {} person& operator=(const person& p) //赋值运算符重载 { if (this != &p) { _name = p._name; } return *this; } ~person()//基类析构 {} protected: const char* _name; }; class student :public person { public: student(const char* name, int num)//派生类构造函数 :person(name) , _num(num) {} student(const student& s) //派生类拷贝构造 :person(s) , _num(s._num) {} student & operator=(const student& s) //派生类赋值运算符重载 { if (this != &s) { person::operator=(s); _num = s._num; } return *this; } ~student() //派生类析构 {} protected: int _num; };
上一篇: 炖羊肉汤羊肉需要炒吗