一,基本概念
1,面向对象程序设计四个主要特点:抽象,封装,继承,多态性;
2,类的继承机制主要用于解决软件的重用问题;
3,继承和派生是同一个事件中针对不同个体的说法,子继承于父,父派生出子;
4,单继承:一个派生类只从一个基类派生而来 多重继承:一个派生类有两个或多个基类;
二,派生类的成员
1,无选择地从基类接收全部成员;
2,调整从基类接收的成员:a,访问属性 ; b,在派生类中声明一个和基类成员同名的成员(若为函数,参数列表也要相同);
3,基类的构造函数与析构函数是不能从基类继承的;
4,保护成员,对于本身所在类对象来讲,和私有成员相同,唯一不同的是它还可以被派生类调用。
三,访问属性
1,公有继承 私有--->不可访问 公有--->公有 保护--->保护
私有继承 私有--->不可访问 公有--->私有 保护--->私有
保护继承 私有--->不可访问 公有--->保护 保护--->保护
2,私有继承而来的派生类对象不能引用从基类继承而来的任何成员(因为此时它们在派生类中是私有的),需要通过派生类新增加的公有成员函数调用从基类继承而来的成员。
3,如果想要在派生类中引用基类中的某些成员,应当将基类的这些成员声明为protected,而不要声明为private
四,多级派生
直接派生类,间接派生类,直接基类,间接基类
五,派生类的构造函数
(在执行派生类的构造函数时,调用基类的构造函数)
1,原型:在派生类中声明并定义
Student(int n,string num,char s,int a,string ad):Stduent(n,num,s)
( age = a;
addr = ad;
}
2,在派生类中声明,在类外定义
声明
Student(int n,string num,char s,int a,string ad);
定义
Student(int n,string num,char s,int a,string ad):Stduent(n,num,s)
( age = a;
addr = ad;
}
3,调用基类构造函数时的实参可以是常量,全局变量和派生类构造函数参数列表中的参数
Student(string num,char s,int a,string ad):Student(10010,num,s)
( age = a;
addr = ad;
}
4,初始化表
Student(int n,string num,char s,int a,string ad):Stduent(n,num,s),age(a),addr(ad){}
5,有子对象的派生类
Student(int n,string num,char s,int n1,string num1,int a,string ad):Stduent(n,num,s),monitor(n1,num1)
( age = a;
addr = ad;
}
tips:有多个子对象时,则以此类推在后面继续扩充。
初始化顺序:基类,子对象,派生类
6,多层派生
class Student
{,,,
Student(int n,string nam)
{ num = n;
name = nam;
}
,,,
}
class Student1:public Student
{,,,
Student(int n,string nam,int a):Stuent(n,nam)
{ age = a;
}
,,,
}
class Student2:public Student1
{,,,
Student2(int n,string nam,int a,int s):Student1(n,nam,a)
{ score = s;
}
,,,
}
Int main()
{,,,
Student1 stud(10010,"Li",16,89);
,,,
}
tips:不用列出每一层派生类的构造函数,只需写出其上一层派生类的构造函数即可
初始化顺序:递归调用每一级的构造函数,从最原始的基类开始执行
六,多重继承
1,多重继承的构造函数
和单继承的构造函数形式基本相同,只是在初始化列表中包含多个基类的构造函数
2,多重继承引用的二义性
a,两个基类有同名的成员
用基类名来引用,如 c1.A::a = 3;
b,两个基类和派生类三者都有同名成员。
基类的同名成员在派生类这种被“屏蔽”
引用派生类中的同名成员 c1.a = 5;
引用基类中的同名成员 c1.A::a = 3;
3,如果类A和类B是从同一个基类派生的
用直接基类名来引用
七 虚基类
为了解决(六)中的第三个二义性问题,为了避免在派生类中有重复的相同数据
1,声明
虚基类不是在声明基类时声明的,而是在声明派生类时,因为它可能对于某些派生类来说是虚基类,对于其他派生类来说不是虚基类。另外,每个虚基类的直接派生类中都要有virtual的声明,要不还是会出现重复的数据,达不到虚基类原始的目的。
方法
class A(,,,);
class B:virtual public A(,,,);
class C:virtual public B(,,,);
2,初始化
在最后的派生类中的构造函数,和以往不同,不只要调用直接基类的构造函数,而且要调用虚基类(此时为它的间接基类)的构造函数。当然,此时,虚基类的给几个直接派生类的构造函数也依然要调用虚基类的构造函数,虽然此时虚基类的构造函数会被重复调用,但是编译环境会自动给进行筛选的。
八,基类与派生类的转换(赋值)
只有公用继承的i派生类才可以对起基类对象赋值
1,派生类对象向基类对象赋值;
2,派生类对象可以替代基类对象向基类对象的引用进行赋值或初始化
tips, 所以,此时引用不是像往常一样和等式右边的变量占用同一段内存空间,此时只是和右式的一部分占用同一段内存空间。
3,如果函数的参数是基类对象或基类对象的引用,相应的实参可以用子类对象
4,派生类对象的地址可以赋值给指向基类对象的指针变量
九 继承与组合
1,类的组合:在一个类中以另一个类的对象作为数据成员
2,类的组合和继承一样是软件从重用的重要方式,都是利用已有类的资源。继承是纵向的,组合是横向的。