资源预览内容
第1页 / 共60页
第2页 / 共60页
第3页 / 共60页
第4页 / 共60页
第5页 / 共60页
第6页 / 共60页
第7页 / 共60页
第8页 / 共60页
第9页 / 共60页
第10页 / 共60页
亲,该文档总共60页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
面向对象(继承),第四章,2,目标,继承访问控制继承中的构造函数和析构函数函数覆盖,3,什么是继承,为什么要继承,继承是事物发展的过程,通过继承,使后代继承了父辈的一切优秀的品质,并在该品质上又进一步发展形成了超越父辈的品质和能力,机动性,机动性,超音速,机动性,超音速,隐型,机动性,超音速,隐型,超视距,4,继承的意义,人类的发展离不开继承,如果不使用继承,则知识无法传承、经验无法延续,更不要说站在前人的肩膀上再进一步的愿望。继承-获得前人的知识和经验继承-在前人的基础上继续发展,5,继承的概念(一),继承是现实生活中的经常使用的术语.例如:孩子继承其父母的特征.继承意味着某人或某物从另一个人或实体中派生出一组属性.类似的,在C+中一个类也可以从另一个类继承或派生,从一个旧类派生一个新类的过程称为继承,6,继承的概念(二),继承或派生另一个类的类叫派生类,而派生出这个派生类的类叫作基类.派生类的每个实例包括了基类的大多数属性;因此,派生类与其基类相比有更大的属性集.然而,派生类能够修改基类的部分或者全部属性.因此,继承使代码的重用性更加容易实现,7,继承的概念(三),一旦定义并测试过一个基类,就不需要修改它了,但是其他程序员可以调整它以满足他们的需要.从现有类派生一个新类允许重新定义其基类的成员函数,还允许向派生类添加新成员,基类不需要重新编译,它在继承的过程中保持不变,重用现有代码可以节省时间和精力,还能保证程序的可靠性,8,继承的特征,继承是允许重用现有类来构造新类的特性,基类,方法和属性,9,优点(一),使代码具有可重用性通过继承类库拥有类库的能力-用别人的类为基础创建自己需要的类,可以省时省力可以重定义基类的成员函数,实现新的功能-对别人的类中的不足重新实现,但是又不改变别人的类.,10,优点(二),向派生类添加新成员,实现功能发展和扩展-基于对别人的类的基础上,实现新的类,当然,新类必须具备上一代类所不具备的能力不需要了解核心技术的细节,就能拥有别人的能力-简单的继承别人的类,可以不需要了解其功能的实现细节,就可以直接使用,11,单一继承,只拥有一个父类的新类的创建过程从一个现有基类创建新类的过程,父类,子类,单一继承,多重继承,12,单一继承,处理某企业中雇员的程序,使用一个箭头从派生类指向基类表示派生类引用基类的函数和数据,而基类没有访问派生类的权限,13,基类和派生类,派生类的声明必须指定基类的名称class Manager : public Employee任何类都能用作基类基类分为两种类型直接基类间接基类,14,直接基类和间接基类,直接基类class A ;class B : public A /A是B的直接基类 ;间接基类class A ;class B : public A ;class C : public B /A是C的间接基类 ;,15,继承的类型,16,单一继承,class A;class B :public A;,17,多级继承,class A; class B : public A;class C : public B;,18,层次继承,class A;class B :public A;class C :public A;class D :public C;class E :public C;,19,多重继承,class A;class B;class C :public A, public B;,20,继承特性-访问控制,派生类的函数能够访问基类的保护和公有成员派生类的对象公有派生的类的对象能够访问基类的公有成员公有派生的类的对象不能访问基类的私有和保护成员,21,基类(Employee类),#includeclass Employee private:int privA;protected:int protA;public:int pubA;,22,派生类/子类(Manager类),class Manager:public Employee /这个派生类中没有自己的成员属性public:void fn()int a;a = privA; /错误a = protA;a = pubA;,23,基类与派生类的访问控制,void main()Employee emp; /基类的对象emp.privA = 1; /错误emp.protA = 1; /错误emp.pubA = 1;Manager mgr; /派生类的对象mgr.privA = 1; /错误mgr.protA = 1; /错误mgr.pubA = 1;,24,可访问性,基类的成员函数或数据何时能够被派生类的对象使用无论类成员是私有、公有还是保护,它们总是能够由自身的成员函数访问在类的外部定义的对象只能访问类的公有成员,25,访问基类成员,在继承中,如果基类的成员是公有和保护的,那么派生类成员能够访问基类的成员派生类成员不能访问基类的私有成员,26,protected访问控制说明符,保护部分类似于私有部分只能被其所属类的成员访问不能被类外部的对象或函数访问区别只有在派生类中才会表现出来,27,访问控制说明符的规则,类成员总是能够被它们自己的类的方法访问继承类能访问基类的公有或保护成员公有成员可以在任何地方被访问,28,访问控制 3-2,29,访问控制说明符,class 派生类:访问控制说明符 基类例如: class Manager : public Employee访问控制说明符有三种类型:public,private,protected,它们说明了派生类对基类属性继承的3种方式,30,访问控制,派生类不能访问基类的私有成员公有继承不改变基类成员的访问级别基类的另外两种访问级别使得所有继承的成员与基类成员(私有基类的私有成员或保护基类的保护成员)属于相同的访问级别, 比如:私有和保护派生的类将本来可以访问的基类成员(公有和保护)/(公有)改变为私有或保护成员,31,访问控制的访问改变,正如右图上太阳的3种颜色的光被滤镜过滤后,只能在地球上留下滤镜颜色的光。因此,用public控制的继承不改变基类的成员,而protected和private的控制继承将会改变基类成员变为protected或private的访问方式,滤镜,太阳,地球,32,public,private protected public,33,公有派生(不改变基类成员),#includeclass Aprivate:int privA;protected:int protA;public:int pubA;/通过公有派生的类class B:public A public:void fn()int a;a = privA; /错误,a = protA;a = pubA;void main()B obj1; /派生类的对象obj1.privA = 1; /错误obj1.protA = 1; /错误obj1.pubA = 1;,34,protected,private protected public,35,保护派生(改变基类公有成员为保护),#includeclass Aprivate:int privA;protected:int protA;public:int pubA;/通过保护派生的类class C:protected A public:void fn()int a;a = privA; /错误,a = protA;a = pubA;void main()C obj2; /派生类的对象obj2.privA = 1; /错误obj2.protA = 1; /错误obj2.pubA = 1; /错误,36,private,private protected public,37,私有派生(改变基类公有和保护成员为私有),#includeclass Aprivate:int privA;protected:int protA;public:int pubA;/通过公有派生的类class D:private A public:void fn()int a;a = privA; /错误,a = protA;a = pubA;void main()D obj3; /派生类的对象obj3.privA = 1; /错误obj3.protA = 1; /错误obj3.pubA = 1; /错误,38,基类成员的访问规则,39,作业(一),设计类Employee,它包含私有数据成员姓名,员工号,头衔和部门, 设计该类的一个派生类Manager类,它包含附加私有数据成员额外津贴,和所管理的员工人数,再设计一个派生类Secretary类,它包含一个附加数据成员,用于指定他汇报数据的经理姓名. 编写一个程序用来测试基类和派生类的定义是否合法.,40,41,构造函数在继承中的作用,构造函数是用于将类构造成对象时用来使用的继承表面上看是类的继承,但是实际上,继承是发生在对象层次上的属性和行为的传承,毕竟只有对象才具有现实意义。在继承过程中,父类对象和子类对象将同时存在,我们不可能,也不会看到,没有父类对象的子类对象,毕竟必须先有鸡再有蛋,42,继承中的构造函数,先调用基类的构造函数,然后调用派生类的构造函数class Baseprotected: int a;public: Base()a = 0;/默认构造函数 Base(int c) a = c; /单参数构造函数;class Derived : public Basepublic: Derived(): Base() /默认构造函数 Derived(int c): Base(c) /单参数构造函数;,43,继承中的构造函数,当声明派生类的对象时,Derived obj; 它将会首先调用基类的构造函数,然后调用派生类的构造函数基类构造函数是在派生类构造函数之后指定的,使用冒号分隔Derived(): Base(),44,继承中的构造函数,在派生类的构造函数调用中显式选择基类的构造函数,如果不指定,派生类将会自己选择基类的默认构造函数Derived obj1(20);调用基类中的相应构造函数Derived(int c): Base(c);派生类的参数C不仅给派生类用,还要作为基类构造函数的参数,45,显示调用基类构造函数,#include class Base public:int zz;Base(int a)zz = a;class Derived: public Base public:int ss;Derived(int a,int b):Base(b),
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号