06、面向对象程序实现-继承与多态性(I)-2010

上传人:宝路 文档编号:52898620 上传时间:2018-08-26 格式:PPT 页数:127 大小:2.42MB
返回 下载 相关 举报
06、面向对象程序实现-继承与多态性(I)-2010_第1页
第1页 / 共127页
06、面向对象程序实现-继承与多态性(I)-2010_第2页
第2页 / 共127页
06、面向对象程序实现-继承与多态性(I)-2010_第3页
第3页 / 共127页
06、面向对象程序实现-继承与多态性(I)-2010_第4页
第4页 / 共127页
06、面向对象程序实现-继承与多态性(I)-2010_第5页
第5页 / 共127页
点击查看更多>>
资源描述

《06、面向对象程序实现-继承与多态性(I)-2010》由会员分享,可在线阅读,更多相关《06、面向对象程序实现-继承与多态性(I)-2010(127页珍藏版)》请在金锄头文库上搜索。

1、Lecture Notes on Object-Oriented Technology (Programming & Design) (Fall 2010, Bachelor of Computer Science)Duan shihong Office: Room 1203A ,Information Building,第八讲 继承与多态性(I),软件复用及其途径 继承:泛化的实现 继承中的对象初始化与收尾 多继承与重复继承 继承的实例:纸牌游戏 主题讨论:存储模型,与继承相关的两个设计原则,两种is-a关系 分类(classification):描述实例与类型之间的关系。 Tommy i

2、s a cat. 泛化(generalization):描述类型与类型之间的关系(子类型关系)。 Cats are animals. 注意它们的区别 泛化关系具有传递性;而分类关系不具有传递性。 继承所指的is-a关系是指泛化,而不是分类。 有学者提出新名词:用kind-of关系代替is-a关系。 The cat ia a kind of animals.,继承是is-a关系在程序中的实现 is-a关系:在问题空间中描述概念与概念之间的关系。 利用现有概念来定义一个新的概念。 继承关系:在解空间中描述类与类之间的关系。 利用现有的类来定义一个新的类。 软件复用的思想 面向对象设计的一个重要指导

3、原则是:不要每次都从头开始定义一个新的类,而是将这个新的类作为一个或若干个现有类的泛化或特化。,继承机制,class Xint i; public:X( ) i = 0; void f(); ;class Yint j; public:X x;Y( ) i = 0; ;,main() Y y;y.x.f(); ,(composition),继承,class Box public: int width, height; void SetWidth(int);void SetHeight(int); ;,class ColoredBox:public Box public: int color;

4、void SetColor(int); ;,ColoredBox cb; void main() cb.SetWidth(5); cb.SetHeight(5); cb.SetColor(6); ),class Cleanser private: string s;protected: void append(string a) s += a; public: Cleanser() s = “Cleanser”;void dilute() append(“ dilute()“); void apply() append(“ apply()“); void scrub() append(“ sc

5、rub()“); void print() coutsscrub(); /! Detergent *d = new Cleanser(); /! D-foam();,incompatible types,静态类型 vs 动态类型 静态类型:声明obj时的类型(在编译时确定的类型)。 动态类型:在运行时某一时刻与obj相关联的对象的类型。 由于基本类型的静态与动态类型没有区别,故只需讨论引用类型。 动态类型必须是静态类型的子类型!,Cleanser *c = new Detergent();,c的静态类型,c的动态类型,对继承的狙击 有时候并不希望由客户程序自定义的子类代替某些类! Java里有

6、很好的机制将一个类定义为final的或者将一个成员定义 为final的。 C+里如何实现禁止类被派生? 解决方案 1 构造函数声明为私有的。如果用户从该类派生一个类,那么在编译阶段就会得到一个不能访问私有成员函数的错误信息。 2 创建伪造的构造函数:静态,返回的是对象指针 3 注意:用户在使用完该类对象后需要调用delete,释放资源。也可使用智能指针。,class ClxNotBase public: ClxNotBase(); private: ClxNotBase(); ClxNotBase(const ClxNotBase,构造函数私有,禁止派生,如果把类的构造函数声明为私有的,那么我

7、们就无法构造这个类的对象,,class ClxNotBase public: ClxNotBase(); static ClxNotBase * NewlxNotBase(); static ClxNotBase * NewlxNotBase(const ClxNotBase ,创建伪造的构造函数,如果把类的构造函数声明为私有的,那么我们就无法构造这个类的对象,,两种不同的继承模式 重定义(overriding):仅重定义父类的操作而不引入新特征。 是比扩充更为重要、更加常见的继承模式。 子类型的接口与父类型完全相同,两者是完全相同的类型。 扩充(extending):引入父类所没有的新特征。

8、 子类型与父类型有区别:更加丰富的内容,是父类型的特例。 Java语言的保留字extends表明了这种继承。 实际应用通常是上述两种方式的结合。,继承的模式,重定义的继承模式(is-a),扩充的继承模式(is-like-a),注意圆与点之间 关系不是has-a关系,将圆看作一种 带有半径的点,C+派生类的定义格式,class 派生类名:继承方式 基类名 public:/派生类公有成员private:/派生类私有成员;,派生类只有 一个直接基 类为单继承,例: 定义基类Pen,class Pen public:enum ink off,on;void set_status (ink);void

9、set_location (int, int); private:int x; int y;int status; /状态;,定义派生类(彩色钢笔),class CPen: public Pen public:void set_color(int); private:int color; ;,color,set_color,继承概念1 - 继承方式,三种继承方式: 公有继承(public), 私有继承(private), 保护继承(protected),不同继承方式的影响主要体现在: 派生类成员对从基类继承的成员的访问控制。 派生类对象对从基类继承成员的访问控制。,继承方式继承的访问控制,不同

10、的继承方式使得派生类从基类继承的成员具有不同的访问控制权限,以实现数据的安全性和共享性控制。派生类成员(继承的成员自增加的成员)的访问权限: 1)inaccessible(不可访问) 2)public 3)private 4)protected,公有继承(public),基类的public和protected成员的访问属性在派生类中保持不变,但基类的private成员不可访问。 派生类中的成员函数可以直接访问基类中的public和protected成员,但不能访问基类的private成员。 通过派生类的对象只能访问基类的public成员。,参见程序derive工程,公有继承举例,class P

11、oint /基类Point类的声明 public: /公有函数成员void InitP(float xx=0, float yy=0)X=xx;Y=yy;void Move(float xOff, float yOff)X+=xOff;Y+=yOff;float GetX( ) return X;float GetY( ) return Y; private: /私有数据成员float X,Y; protected: /受保护数据成员int a,b; ;,class Rectangle: public Point /派生类声明 public: /新增公有函数成员void InitR(float

12、 x, float y, float w, float h)InitP(x,y);W=w;H=h;/调用基类公有成员函数float GetH( ) return H;float GetW( ) return W; private: /新增私有数据成员float W,H; ;,InitP,public,Move,public,GetX,public,GetY,public,X,Y,inaccessible,a,b,protected,X=2;可否?,a=2;可否?,#include #includeint main( ) Rectangle rect;rect.InitR(2,3,20,10);/通过派生类对象访问基类公有成员rect.Move(3,2); cout , ,rect.GetH( ),rect.GetW( )endl;return 0; ,rect.GetX ( ),rect.GetY( ),

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 中学教育 > 教学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号