第04章 类的继承与派生
- 格式:ppt
- 大小:147.50 KB
- 文档页数:37
第四章继承和派生§4—1 继承§4—2 单继承§4—3多继承§4—1 继承一、继承的含义①面向对象方法提供了从问题域到解域的自然映射客观世界中的对象既有共性,也有个性,通过不同程度的抽象,形成了分类和层次结构不同层次的类之间体现了概括(generalize)和特化(specify)关系把高层次的类称为父类、超类和基类,把由该类特化产生的低层次类称为子类或派生类派生类不仅具有基类的属性和行为,还具有自己特有的属性和行为②在不同类之间,除了概括和特化的关系外,还有聚合和分解关系模块化的主要目的是实现软件的可复用性从模块的角度看,继承是一种关键性的复用技术③继承机制提供了一种充分利用现有资源的方法它既体现了经济思想,又体现了谦虚精神:我比别人看得远,是因我站在巨人的肩上——牛顿继承使得在创建新类时,只需说明新类与基类的区别,从而大量原有代码都可复用④派生类是基类的具体化,是基类定义的延续在多继承时,派生类也是基类的组合二、继承的概念1.基类即父类,超类,是已存在的用来派生新类的类,是被继承的类2.派生类即子类,是由己存在的类派生出的新类,是继承其他类特性的类3.单继承即单重继承,每个派生类只有一个直接父类是从一个基类派生的继承,形成类的层次,像一棵树4.多继承即多重继承,派生类可以有多个直接父类是从多个基类派生的继承,形成一个有向无环图(DAG图)5.类的层次结构直接基类、间接基类、直接派生类、间接派生类多层继承:一个基类可以是另一个基类的派生类区别:多层继承和多重继承三、派生类的定义①单继承class 派生类名: 继承方式基类名{派生类新定义成员;};②多继承class 派生类名: 继承方式1 基类名1,继承方式2 基类名2,……{派生类新定义成员;};四、继承方式共有三种:公有继承:public保护继承:protected私有继承:private 可缺省继承方式基类特性派生类特性公有继承public publicprotectedprivatepublicprotected不可访问或不可见保护继承public protectedprotected protectedprivate protected 不可访问私有继承(缺省)private publicprotectedprivateprivateprivate不可访问派生类不能继承基类的构造函数、析构函数和友元1.基类的私有成员只能被基类中的成员函数和友元函数访问,不能被其他函数访问2.基类的保护成员只能被基类及其派生类中的成员函数和友元函数访问3.公有继承派生类的对象可以访问基类中的公有成员派生类的成员函数可以访问基类中的公有成员和保护成员4.保护继承和私有继承派生类的对象不能访问基类中的任何成员派生类的成员函数可以访问基类中的公有和保护成员5.私有继承基类的公有和保护成员只能由直接派生类访问,无法再往下继承§4—2 单继承每个派生类只有一个直接基类,但每个基类可以有多个派生类一、成员访问权限的控制二、成员访问权限的调整①保护继承和私有继承将改变基类的公有和保护成员在派生类中的访问权限属性,若欲恢复其访问权限,则应作调整②方法:在派生类相应访问权限段中加以说明:基类名:: 成员名;③访问声明只能对变量或函数名,不能说明类型和参数④基类成员被调整后,在派生类中的访问权限既不能扩大也不能减小,即不能改变所属权限段⑤私有成员的访问权限不可调整,不能对私有段成员作访问声明⑥重载函数只需一个声明即可,具有不同访问权限的重载函数名不能作访问声明三、派生类的成员(1)由两部分组成:①派生类从基类继承来的成员,其封装体叫基类子对象(匿名对象)②派生类自定义成员(2)派生类对象的内存长度是基类数据成员和派生类自定义数据成员的内存空间之和(3)基类的私有成员在派生类中存在,但不可访问,不可见(4)静态成员受访问权限符的限制,但不受继承方式的制约派生类可用“基类名:: 静态成员名”访问基类的static成员(5)派生类共有四种成员:①公有成员②保护成员③私有成员④不可直接访问的成员,它由基类私有成员派生而来的(6)派生类直接访问基类私有成员的方法:①将基类私有段成员放于基类保护段②将派生类或派生类的成员函数声明为基类的友元四、改造基类成员(1)通过继承方式来控制基类成员在派生类中的访问权限(2)对基类成员进行同名覆盖①在派生类中声明一个与基类成员同名的新成员以屏蔽(隐藏)基类同名成员②在派生类中或通过派生类对象只能访问到派生类中新定义的同名成员③若在派生类中欲调用被编译器隐蔽起来的基类同名成员,则应作访问声明,明确指定基类类范围:对象名.基类名:: 成员名对象名.基类名:: 成员函数名(参数表)④同名覆盖时要求派生类与基类同名的新成员函数原型相同,数据成员的名字和类型相同当同名的基类成员函数和派生类成员函数的参数个数、类型和顺序不完全相同时,则属于函数重载⑤当欲对从基类继承过来的某些函数功能进行扩充和改造时,都可用同名覆盖原则来实现五、派生类的构造函数(1)派生类对象的数据结构,由基类数据成员和派生类自定义数据成员共同构成(2)构造函数不能被继承,基类子对象只能通过基类构函来初始化,常以成员初始化列表方式进行(3)定义:派生类名(总参数表):基类名(参数表),子对象名(参数表2),……{派生类自定义数据成员的初始化;}(4)派生类构造函数的调用执行顺序:①基类构造函数:先兄长②子对象类的构函:后客人③派生类构函:最后自己(5)当基类有无参数或缺省构函或未显式定义任何构函时,派生类构函中可省去对基类构函的调用(6)当基类构函有参数时,则派生类必须定义构函,以提供参数传递的途径(7)当派生类的基类也是一个派生类时,则每个派生类只需负责其直接基类构函的调用六、派生类的析构函数(1)析构函数不能被继承,基类子对象只能通过基类析构函数类释放(2)析构函数调用执行顺序与构函相反:①派生类析构函数:先自己②子对象类析构函数:再客人③基类析构函数:最后兄长七、赋值相容原理(1)即当派生类从基类公有继承时,派生类对象可自动隐式地转换一个基类对象(2)当公有继承时,在需要基类对象的任何地方,都可以使用公有派生类的对象来替代即公有派生类对象可以作为基类对象使用,但只能使用从基类继承来的成员(基类子对象)(3)公有派生类的对象、对象指针、对象引用都适用于基类对象、对象指针、对象引用所能使用的场合(4)赋值相容性不可逆若欲将基类对象指针转换成公有派生类对象指针,则必须显式进行类型转换不允许用基类对象给派生类对象赋值(5)也称为子类型对父类型的类型适应①子类型:对类型S,当且仅当它至少提供了类型T的行为,则称S是T的子类型②公有继承时,基类为父类型,派生类为子类型,派生类适应于基类③类型适应:若一个函数可用于父类型的对象,则它也可用于其各个子类型的对象(6)是多态性的基础,提高了编程效率八、多层继承(1)所有派生类都只需对其直接基类负责:派生类构函只需向其直接基类传递参数(2)可实现抽象机制和软件重用机制§4—3多继承一、多继承即多重继承①是单继承的扩展和组合,单继承可看作是多继承的特例②派生类有两个或两个以上的直接基类③派生类与每个基类之间仍可看作单继承④赋值相容性原理对多继承同样成立⑤同名覆盖规则对多继承仍成立⑥一个类不能多次被说明为同一个派生类的直接基类,即一个类不可以从同一个类中直接继承一次以上(可改用子对象方式)⑦可采用DAG图示法来表示各个基类与派生类的关系:箭头指向基类⑧一个类可以多次成为同一个派生类的间接基类二、多继承的构造函数与析构函数(1)定义:派生类名(总参数表):基类名1(参数表1),基类名2(参数表2),…,子对象名(参数表n),……{派生类构造函数体;}(2)派生类构函调用执行顺序:(与单继承相同)①先执行基类构函:先兄长②再执行子对象类构函:再客人③最后执行派生类本身的构函:最后自己(3)处于同一层次的各基类构函的执行顺序取决于定义派生类时所指定的各基类顺序,与派生类构函定义的成员初始化列表各项顺序无关(4)析构函数的调用执行顺序与构函相反三、多继承中的二义性问题(1)即派生类对基类成员访问的不唯一性(继承的模糊性)(2)调用不同基类的相同成员时可能出现二义性措施:使用作用域运算符,用类名对成员加以限定3)访问共同基类的成员时可能出现二义性措施:①用类名限定法来消除二义性,只能用派生类的直接类名来限定②在派生类中重定义一个与基类中同名的成员,以覆盖之③将公共基类说明为虚基类,使之在派生类中只有一个拷贝4)二义性检查是在访问控制和类型检查之前进行的,故只要不同基类有同名成员时,均会出现二义性,即使只有一个可被派生类访问或只有一个名字的类型符合要求(5)存在二义性,则编译时出错§4—4 虚基类1.即虚拟基类2.若类A是派生类C多条继承路径上的一个公共基类,则A在C的对象中将产生多个基类子对象若欲使其只有一个拷贝,则需将A设置为虚拟基类3.引入虚基类的目的:解决二义性问题,使派生类中只有公共基类的一个数据副本4.定义:class 派生类名:virtual 继承方式基类名5.虚基类子对象只被初始化一次,虚基类构函也只被执行一次6.若虚基类构函带有参数,则其直接或间接派生类的构函成员初始化列表中均应列出对虚基类构函的调用,但只有最后派生出来的用于声明对象的类对虚基类构函的调用才会被执行7.在同一层次中,虚基类构函先于非虚基类构函执行8.可节省内存空间,程序也更简洁9.一个类在作为某些类的虚基类的同时,还可以作为另一些派生类的非虚基类10.若虚基类由非虚基类派生而来,则先调用基类构函,再调用派生虚基类构函11.virtual常用于声明虚基类的直接派生类,可放于继承方式前,也可放于继承方式后面12.多继承时,virtual后紧跟的基类为虚基类,若有多个虚基类,则应用多个virtual来说明13.若同一层次中有多个虚基类,则其构函执行顺序取决于派生类定义时指定的顺序。
在Python中,类的继承和派生是通过`class`关键字和继承的语法来实现的。
类的继承允许一个类继承另一个类的属性和方法。
当一个类继承另一个类时,它会自动获得父类的所有属性和方法,并且可以添加或覆盖它们。
下面是一个简单的例子,展示了如何创建一个子类并继承父类的属性和方法:
在这个例子中,`Dog`类继承了`Animal`类。
`Dog`类覆盖了`speak`方法,使其
输出不同的声音。
除了继承属性和方法之外,子类还可以添加新的属性和方法。
例如:
在这个例子中,`Dog`类添加了一个新的方法`run`。
这样,`Dog`类不仅继承了`Animal`类的所有属性和方法,还添加了新的方法。