第15课 - 惊艳的继承
一.继承的概念
1.1 面向对象中继承指类之间的父子关系
1.1.1 子类拥有父类的所有成员变量和成员函数
1.1.2 子类就是一种特殊的父类
1.1.3 子类对象可以当作父类对象使用
1.1.4 子类可以拥有父类没有的行为和属性
二.继承初体验
Source Example2: #include <iostream> #include <stdio.h> #include <stdlib.h> class Parent{ private: int a; public: Parent() { a = 100; } void print() { printf("a = %d\n", a); } }; /* 继承Parent */ class Child : Parent{ }; int main() { Parent parent; Child child; parent.print(); /* 编译会报错,具体原因见下面 */ child.print(); return 0; }
三.深入了解继承
3.1 C++中的访问级别与继承
3.1.1 继承时的访问级别设定会影响到成员的访问级别
class Child :Parent <==> class child : private Parent
私有继承
1. C++中class继承默认为private继承
2. private继承的子类拥有父类的所有成员
3. private继承是的父类的所有成员在子类中为private成员
(在上面的代码中a与print函数成为了private成员,因此无法访问)
3.1.2 C++中存在private继承和public继承
private继承->父类的成员在子类中变为private成员
public继承->父类成员在子类中保持原有访问级别
(通常指的继承都是public继承)Source Example3.1: #include <iostream> #include <stdio.h> #include <stdlib.h> class Parent{ private: int a; public: Parent() { a = 100; } void print() { printf("a = %d\n", a); } }; /* public继承 */ class Child : public Parent{ }; int main() { Parent parent; Child child; /* 下面代码编译不过,因为即使是public继承,a在子类中保持父类中的权限,都是private*/ //child.a = 100; parent.print(); child.print(); return 0; }
3.2 为子类添加新成员
Source Example3.2: #include <iostream> #include <stdio.h> #include <stdlib.h> class Parent{ private: int a; public: Parent() { a = 100; } void print() { printf("a = %d\n", a); } }; /* 继承Parent */ class Child : public Parent{ private: public: /* 执行该函数时,编译会报错 * 因为私有成员只能在本类内部被访问 * a在child类里面属于外部 */ void set(int a, int b) { this->a = a; this->b = b; } }; int main() { Parent parent; Child child; parent.print(); child.print(); child.set(1,2); return 0; }
3.3 类成员的访问级别只有public和private是否足够?
新的关键字protected
类的pritected成员:
protected成员可以在子类中被访问,但不能在外界被访问
protected成员介于public和private之间
Source Example3.3: #include <iostream> #include <stdio.h> #include <stdlib.h> class Parent{ protected: int a; public: Parent() { a = 100; } void print() { printf("a = %d\n", a); } }; /* 继承Parent */ class Child : public Parent{ protected: int b; public: void set(int a, int b) { this->a = a; this->b = b; } }; int main() { Parent parent; Child child; parent.print(); child.print(); child.set(1,2); /* a是有protected修饰的,可以由子类访问,但是不能由外界访问 */ //parent.a = 1000; return 0; }
四.如何恰当的使用public,protected和private成员声明访问级别?
4.1 类成员访问级别设置的原则
4.1.1 需要被外界访问的成员直接设置为public
4.1.2 只能在当前类中访问的成员设置为private
(为了进行代码复用,一般设置为protected)
4.1.3 只能在当前类和子类中访问的成员设置为protected
注意:private成员在子类依然存在,但是却无法访问到五.C++中的protected继承(很少用到)
如果是public继承,访问级别保持父类的访问级别不变
如果是protected继承,父类中的public变为protected,其余保持不变
如果是private继承,所有的都变为private权限
Source Example5: #include <iostream> #include <stdio.h> #include <stdlib.h> class Parent{ private: int a; protected: int b; public: int c; Parent() { a = 0; b = 0; c = 0; } void set(int a, int b, int c) { this->a = a; this->b = b; this->c = c; } void print() { printf ("a = %d\n",a); printf ("b = %d\n",b); printf ("c = %d\n",c); } }; class A : public Parent { public: void print() { /* public继承,a的权限与父类中保持一致,都是private,子类无法访问 */ // printf ("a = %d\n",a); //Error printf ("b = %d\n",b); printf ("c = %d\n",c); } }; class B : protected Parent { public: void print() { /* a是private属性,无法访问 */ // printf ("a = %d\n",a); //Error printf ("b = %d\n",b); printf ("c = %d\n",c); } }; class C : private Parent { public: void print() { /* a是private属性,无法访问 */ //printf ("a = %d\n",a); //Error printf ("b = %d\n",b); printf ("c = %d\n",c); } }; int main() { Parent p; A a; B b; C c; p.c = 100; a.c = 100; /* b是public继承,c是public属性,因此c在b中是protected属性,无法在外界访问 */ //b.c = 100; //Error //c.c = 100; //Error p.set(1,2,3); a.set(1,2,3); //b.set(1,2,3);//Error //c.set(1,2,3);//Error a.print(); b.print(); b.print(); return 0; }