三,继承方式&访问限定符
派生类可以继承基类中除了构造函数和析构函数之外的所有成员,但是这些成员的访问属性是由继承方式决定的。
不同的继承方式下基类成员在派生类中的访问属性:
举例说明:
(1)public继承
eg1:
#include <iostream> using namespace std; class Person { public://公有数据成员 int length;//身高 int weight;//体重 }; class Student:public Person { public: void test1() { length = 183;//子类中可访问父类的共有成员(包括属性和方法) weight = 70; total = 300; } private: int total;//总分 char* school;//学校 }; void Funtest() { Student s1; s1.length = 160;//类外派生类的对象可访问基类的公有成员(包括属性和方法) s1.weight = 45; } int main() { Funtest(); return 0; }
由上述例子可得出:公有继承中,派生类中可访问基类的公有成员(包括属性和方法),类外派生类的对象可访问基类的公有成员(包括属性和方法)
eg2:
#include <iostream> using namespace std; class Person { protected://保护数据成员 int length;//身高 int weight;//体重 }; class Student:public Person { public: void test1() { length = 183;//子类中可访问父类的保护成员(包括属性和方法) weight = 70; total = 300; } private: int total;//总分 char* school;//学校 }; void Funtest() { Student s1; s1.length = 160;//类外派生类的对象不可访问基类的保护成员(包括属性和方法) s1.weight = 45; } int main() { Funtest(); return 0; }
编译结果:
由上述例子可得出:公有继承中,派生类中可访问基类的保护成员(包括属性和方法),类外派生类的对象不可以访问基类的保护成员(包括属性和方法)
eg3:
#include <iostream> using namespace std; class Person { private://私有数据成员 int length;//身高 }; class Student:public Person { public: void test1() { length = 183;//子类中不可以访问父类的私有成员(包括属性和方法) } }; void Funtest() { Student s1; s1.length = 160;//类外派生类的对象不可以访问基类的私有成员(包括属性和方法) } int main() { Funtest(); return 0; }
编译结果:
由上述例子可得出:公有继承中,派生类中不可以访问基类的私有成员(包括属性和方法),类外派生类的对象不可以访问基类的私有成员(包括属性和方法)
(二)保护继承
eg1:
#include <iostream> using namespace std; class Person { public://公有数据成员 int length;//身高 }; class Student:protected Person { public: void test1() { length = 183;//子类中可以访问父类的公有私有成员(包括属性和方法) } }; void Funtest() { Student s1; s1.length = 160;//类外派生类的对象不可以访问基类的公有成员(包括属性和方法) } int main() { Funtest(); return 0; }
编译结果:
结论:保护继承中,派生类中可以访问基类的公有成员(包括属性和方法),类外派生类的对象不可以访问基类的私有成员(包括属性和方法)
eg2:
#include <iostream> using namespace std; class Person { protected://保护数据成员 int length;//身高 }; class Student:protected Person { public: void test1() { length = 183;//子类中可以访问父类的保护成员(包括属性和方法) } }; void Funtest() { Student s1; s1.length = 160;//类外派生类的对象不可以访问基类的保护成员(包括属性和方法) } int main() { Funtest(); return 0; }
编译结果:
结论:保护继承中,派生类中可以访问基类的保护成员(包括属性和方法),类外派生类的对象不可以访问基类的保护成员(包括属性和方法)
eg3:
#include <iostream> using namespace std; class Person { private://私有数据成员 int length;//身高 }; class Student:protected Person { public: void test1() { length = 183;//子类中可以访问父类的私有成员(包括属性和方法) } }; void Funtest() { Student s1; s1.length = 160;//类外派生类的对象不可以访问基类的私有成员(包括属性和方法) } int main() { Funtest(); return 0; }
编译结果:
结论:保护继承中,派生类中不可以访问基类的私有成员(包括属性和方法),类外派生类的对象不可以访问基类的私有成员(包括属性和方法)
(三)私有继承
eg1:
#include <iostream> using namespace std; class Person { public://公有数据成员 int length;//身高 }; class Student:private Person { public: void test1() { length = 183;//子类中可以访问父类的公有成员(包括属性和方法) } }; void Funtest() { Student s1; s1.length = 160;//类外派生类的对象不可以访问基类的公有成员(包括属性和方法) } int main() { Funtest(); return 0; }
运行结果:
结论:私有继承中,派生类中可以访问基类的公有成员(包括属性和方法),类外派生类的对象不可以访问基类的公有成员(包括属性和方法)
eg2:
#include <iostream> using namespace std; class Person { protected://保护数据成员 int length;//身高 }; class Student:private Person { public: void test1() { length = 183;//子类中可以访问父类的保护成员(包括属性和方法) } }; void Funtest() { Student s1; s1.length = 160;//类外派生类的对象不可以访问基类的保护成员(包括属性和方法) } int main() { Funtest(); return 0; }
运行结果:
结论:私有继承中,派生类中可以访问基类的保护成员(包括属性和方法),类外派生类的对象不可以访问基类的保护成员(包括属性和方法)
eg3:
#include <iostream> using namespace std; class Person { private://私有数据成员 int length;//身高 }; class Student:private Person { public: void test1() { length = 183;//子类中不可以访问父类的私有成员(包括属性和方法) } }; void Funtest() { Student s1; s1.length = 160;//类外派生类的对象不可以访问基类的私有成员(包括属性和方法) } int main() { Funtest(); return 0; }
运行结果:
结论:私有继承中,派生类中不可以访问基类的私有成员(包括属性和方法),类外派生类的对象不可以访问基类的私有成员(包括属性和方法)
总结:
三种继承方式下,在派生类中均可访问基类的共有成员和保护成员,私有成员不能访问(因为基类和派生类不属于同一作用域).
公有继承中, 在类外通过子类的对象可访问基类的公有成员(包括成员数据和成员函数),其他情况在类外均访问不了。
保护继承中,派生类中基类的public成员降级为protected,protected降级为private。
私有继承中,派生类中基类的public成员降级为private,protected降级为private。
派生类继承了除基类的构造函数和析构函数之外的所有成员,稍后讲解。
public继承是一个接口继承,保持is-a原则。每个父类可用的成员对子类都可用,每个子类成员都可看做一个父类成员。
private和protected是实现继承,保持has-a原则。类似一组合/聚合。但它比组合更低级,当一个派生类对象需要访问基类的保护成员或需要重新定义虚函数时它就是合理的,绝大多数情况下我们都会选择public继承。
(未完待续....)