第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;
}