软件编程思想_第1页
软件编程思想_第2页
软件编程思想_第3页
软件编程思想_第4页
软件编程思想_第5页
已阅读5页,还剩68页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、软件编程思想 第十三章 面向对象编程 引言 面向对象编程 类 实例 绑定与方法调用 子类,派生和继承 内建函数 定制类 私有性 授权与包装 新式类的高级特性 软件编程思想 class MyNewObjectType(bases): define MyNewObjectType class class_suite #类体 类是对象的定义,而实例是真正的实物 ,它存放了类中所定义的对象的具体信息 软件编程思想 创建一个实例的过程称作实例化,(注意 :没有使用new 关键字): myFirstObject = MyNewObjectType() 软件编程思想 最简单的情况,类仅用作名称空间( nam

2、espaces) class MyData(object): pass mathObj = MyData() mathObj.x = 4 mathObj.y = 5 mathObj.x + mathObj.y 9 mathObj.x * mathObj.y 20 软件编程思想 方法 class MyDataWithMethod(object): # 定义类 def printFoo(self): # 定义方法 print You invoked printFoo()! self代表实例对象本身 软件编程思想 创建一个类(类定义) class AddrBookEntry(object): # 类

3、定义 address book entry class def _init_(self, nm, ph): # 定义构造器 = nm # 设置 name self.phone = ph # 设置 phone print Created instance for:, def updatePhone(self, newph): # 定义方法 self.phone = newph print Updated phone# for:, 软件编程思想 创建实例(实例化) john = AddrBookEntry(John Doe, 408-55

4、5- 1212) #为John Doe 创建实例 jane = AddrBookEntry(Jane Doe, 650-555- 1212) #为Jane Doe 创建实例 john John Doe john.phone 408-555-1212 软件编程思想 方法调用 john.updatePhone(415-555-1212) #更新John Doe 的电话 john.phone 415-555-1212 软件编程思想 创建子类 靠继承来进行子类化是创建和定制新类类 型的一种方式,新的类将保持已存在类所 有的特性,而不会改动原来类的定义(指 对新类的改动不会影响到原来

5、的类) 软件编程思想 class EmplAddrBookEntry(AddrBookEntry): def _init_(self, nm, ph, id, em): AddrBookEntry._init_(self, nm, ph) self.empid = id self.email = em def updateEmail(self, newem): self.email = newem print Updated e-mail address for:, 软件编程思想 john = EmplAddrBookEntry(John Doe, 408-555-1212

6、,42, ) Created instance for: John Doe #给 John Doe 创建实例 john 软件编程思想 john.phone 408-555-1212 john.email john.updatePhone(415-555-1212) Updated phone# for: John Doe john.phone 415-555-1212 john.updateEmail() Updated e-mail address for: John Doe john.email 软件编程思想 面向对象编程 编程的发展已经从简单控制流中按步的指 令序列进入到更有组织的方式中

7、,依靠代 码块可以形成命名子程序和完成既定的功 能。结构化的或过程性编程可以让我们把 程序组织成逻辑块,以便重复或重用。 增强了结构化编程,实现了数据与动作的 融合:数据层和逻辑层现在由一个可用以 创建这些对象的简单抽象层来描述。 软件编程思想 抽象/实现 抽象指对现实世界问题和实体的本质表现 ,行为和特征建模,建立一个相关的子集 ,可以用于描绘程序结构,从而实现这种 模型。抽象不仅包括这种模型的数据属性 ,还定义了这些数据的接口。 对某种抽象的实现就是对此数据及与之相 关接口的现实化. 软件编程思想 封装/接口 封装描述了对数据/信息进行隐藏的观念, 它对数据属性提供接口和访问函数。 在设计

8、时,对数据提供相应的接口,以免 客户程序通过不规范的操作来存取封装 的数据属性。 合成 合成扩充了对类的描述,使得多个不同的 类合成为一个大的类 软件编程思想 派生/继承/继承结构 派生描述了子类的创建,新类保留已存类 类型中所有需要的数据和行为,但允许修 改或者其它的自定义操作,都不会修改原 类的定义。 继承描述了子类属性从祖先类继承这样一 种方式。 继承结构表示多“代”派生,可以描述成 一个“族谱”,连续的子类,与祖先类都 有关系。 软件编程思想 泛化/特化 泛化表示所有子类与其父类及祖先类有一样的特 点. 特化描述所有子类的自定义,也就是,什么属性 让它与其祖先类不同。 多态 对象如何通

9、过他们共同的属性和动作来操作及访 问,而不需考虑他们具体的类。多态表明了动态 (又名,运行时)绑定的存在,允计重载及运行 时类型确定和验证。 软件编程思想 类 类把数据值和行为特性融合在一起,是现实世界 的抽象的实体以编程形式出现。实例是这些对象 的具体化。 类声明与函数声明很相似,头一行用一个相应的 关键字,接下来是一个作为它的定义的代码体 class ClassName(object): class documentation string #类文档 字符串 class_suite #类体 软件编程思想 类的数据属性 class C(object): . foo = 100 print C

10、.foo 100 C.foo = C.foo + 1 print C.foo 101 软件编程思想 方法 class MyClass(object): def myNoActionMethod(self): pass mc = MyClass() MyClass.myNoActionMethod() Traceback (innermost last): File , line 1, in ? MyClass.myNoActionMethod() TypeError: unbound method must be called with class instance 1st argument

11、mc.myNoActionMethod() 软件编程思想 类属性 C._name_ 类的名字(字符串) C._doc_ 类的文档字符串 C._bases_ 类的所有父类构成的元组 C._dict_ 类的属性 C._module_ 类定义所在的模块 C._class_ 实例对应的类 软件编程思想 初始化:通过调用类对象来创建实例 class MyClass(object): # define class 定义类 . pass mc = MyClass() # instantiate class 初始化类 软件编程思想 _init_() 构造器方法 把创建实例的调用当成是对构造器的调用 。解释器创

12、建一个实例后调用的第一个方 法. _del_() 解构器方法 解构器是在实例释放前提供特殊处理功能 的方法. 软件编程思想 class C(P): # class declaration 类声明 def _init_(self): # constructor 构造器 print initialized def _del_(self): # destructor 解构器 P._del_(self) # call parent destructor print deleted c1 = C() # instantiation initialized 实例初始化 initialized c2 = c

13、1 # create additional alias 创建另外一个别名 id(c1), id(c2) (11938912, 11938912) del c1 # remove one reference 清除一个引用 del c2 # remove another reference 清除另一个引用 deleted 软件编程思想 class InstCt(object): count = 0 # count is class attr def _init_(self): # increment count InstCt.count += 1 def _del_(self): # decrem

14、ent count InstCt.count -= 1 def howMany(self): # return count 返回count return InstCt.count 软件编程思想 a = InstTrack() b = InstTrack() b.howMany() 2 a.howMany() 2 del b a.howMany() 1 del a InstTrack.count 0 软件编程思想 实例属性 能够在“运行时”创建实例属性 设置实例的属性可以在实例创建后任意时 间进行,也可以在能够访问实例的代码中 进行。 软件编程思想 class HotelRoomCalc(obj

15、ect): def _init_(self, rt, sales=0.085, rm=0.1): self.salesTax = sales self.roomTax = rm self.roomRate = rt def calcTotal(self, days=1): daily = round(self.roomRate *14 (1 + self.roomTax + self.salesTax), 2) return float(days) * daily 软件编程思想 实例属性 vs 类属性 类属性仅是与类相关的数据值,类属性和 实例无关,和实例属性不同。 静态成员不会因为实例而改变

16、它们的值 软件编程思想 访问类属性 class C(object): . version = 1.2 # static member c = C() # instantiation C.version # access via class 1.2 c.version # access via instance 1.2 C.version += 0.1 # update via class C.version # class access 类访问 1.3 c.version # instance access, 1.3 # also reflected change 软件编程思想 class F

17、oo(object): . x = 1.5 foo = Foo() foo.x 1.5 foo.x = 1.7 # try to update class attr foo.x # looks good so far. 1.7 Foo.x # nope, just created a new inst attr 1.5 软件编程思想 类属性持久性 class C(object): . spam = 100 # class attribute 类属性 c1 = C() # create an instance 创建一个实例 c1.spam # access class attr thru ins

18、t. 100 C.spam += 100 # update class attribute C.spam # see change in attribute 200 c1.spam # confirm change in attribute 200 软件编程思想 类属性可变 class Foo(object): . x = 2003: poe2 foo = Foo() foo.x 2003: poe2 foo.x2004 = valid path foo.x 2003: poe2, 2004: valid path Foo.x 2003: poe2, 2004: valid path 软件编程

19、思想 绑定和方法调用 调用绑定方法,实例可以调用mc.foo() 调用非绑定方法 class EmplAddrBookEntry(AddrBookEntry): def _init_(self, nm, ph, em): AddrBookEntry._init_(self, nm, ph) self.empid = id self.email = em 软件编程思想 组合 一个类被定义后,目标就是要把它当成一 个模块来使用,并把这些对象嵌入到你的 代码中去,同其它数据类型及逻辑执行流 混合使用。 组合(composition)。就是让不同的类混合 并加入到其它类中,来增加功能和代码重 用性。

20、软件编程思想 class NewAddrBookEntry(object): # class definition def _init_(self, nm, ph): # define constructor 定义构造器 = Name(nm) # create Name instance self.phone = Phone(ph) # create Phone instance print Created instance for:, 软件编程思想 子类和派生 创建子类 class SubClassName (ParentClass1, ParentC

21、lass2, .): class_suite 如果你的类没有从任何祖先类派生,可以使用object 作 为父类的名字。经典类的声明唯一不同之处在于其没有 从祖先类派生此时,没有圆括号: class ClassicClassWithoutSuperclasses: pass 软件编程思想 class Parent(object): # define parent class def parentMethod(self): print calling parent method class Child(Parent): # define child class def childMethod(se

22、lf): print calling child method p = Parent() # instance of parent 父类的实例 c = Child() # instance of child 子类的实例 c.childMethod() # child calls its method calling child method c.parentMethod() # calls parents method calling parent method 软件编程思想 继承 class P: # parent class 父类 def _init_(self): print insta

23、nce of,self._class_._name_ class C(P): # child class 子类 pass c = C() # child instance 子类实例 instance of C c._class_ # class that created us C._bases_ # childs parent class(es) (,) 软件编程思想 继承覆盖(Overriding)方法 class P(object): def foo(self): print Hi, I am P-foo() p = P() p.foo() Hi, I am P-foo() 软件编程思想

24、class C(P): def foo(self): print Hi, I am C-foo() c = C() c.foo() Hi, I am C-foo() 软件编程思想 class C(P): def foo(self): P.foo(self) # super(C, self).foo() print Hi, I am C-foo() c = C() c.foo() Hi, I am P-foo() Hi, I am C-foo() 软件编程思想 class SortedKeyDict(dict): def keys(self): return sorted(super(Sorte

25、dKeyDict,self).keys() d = SortedKeyDict(zheng-cai, 67), (hui-jun, 68),(xin-yi, 2) print By iterator:. key for key in d print By keys():. d.keys() By iterator: zheng-cai, xin-yi, hui-jun By keys(): hui-jun, xin-yi, zheng-cai 软件编程思想 多重继承 class P1: #(object): # parent class 1 父类1 def foo(self): print c

26、alled P1-foo() class P2: #(object): # parent class 2 父类2 def foo(self): print called P2-foo() def bar(self): print called P2-bar() class C1(P1, P2): # child 1 der. from P1, P2 pass class C2(P1, P2): # child 2 der. from P1, P2 def bar(self): print called C2-bar() class GC(C1, C2): # define grandchild

27、 class 软件编程思想 经典类 gc = GC() gc.foo() # GC = C1 = P1 called P1-foo() gc.bar() # GC = C1 = P1 = P2 called P2-bar() 软件编程思想 新式类 gc = GC() gc.foo() # GC = C1 = C2 = P1 called P1-foo() gc.bar() # GC = C1 = C2 called C2-bar() 软件编程思想 类、实例和其他对象的内建函数 issubclass(sub, sup)布尔函数判断一个 类是另一个类的子类或子孙类。 isinstance(obj1

28、, obj2),判断obj1 是类 obj2 的一个实例,或者是obj2 的子类的 一个实例 软件编程思想 hasattr(), getattr(),setattr(), delattr() class myClass(object): . def _init_(self): . self.foo = 100 myInst = myClass() hasattr(myInst, foo) True getattr(myInst, foo) 100 hasattr(myInst, bar) False 软件编程思想 dir() dir()作用在实例上(经典类或新式类)时,显 示实例变量,还有在实

29、例所在的类及所有它 的基类中定义的方法和类属性。 dir()作用在类上(经典类或新式类)时,则显 示类以及它的所有基类的_dict_中的内容。 dir()作用在模块上时,则显示模块的_dict_ 的内容。 dir()不带参数时,则显示调用者的局部变量。 软件编程思想 vars(obj=None) 返回obj 的属性及其值的一个 字典;如果没有给出obj,vars()显示局部名字 空间字典(属性及其值) class C(object): pass c = C() c.foo = 100 c.bar = Python vars(c) foo: 100, bar: Python 软件编程思想 用特殊

30、方法定制类 C._init_(self, arg1, .) 构造器(带一些可选 的参数) C._new_(self, arg1, .)a 构造器(带一些可选 的参数);通常用在设置不变数据类型的子类。 C._del_(self) 解构器 C._str_(self) 可打印的字符输出;内建str()及 print 语句 C._repr_(self) 运行时的字符串输出;内建repr() 和 操作符 C._unicode_(self)b Unicode 字符串输出;内建 unicode() 软件编程思想 C._call_(self, *args) 表示可调用的实例 C._nonzero_(self

31、) 为object 定义False 值;内建 bool() (从2.2 版开始) C._len_(self) “长度”(可用于类);内建len() C._getattr_(self, attr) 获取属性;内建getattr() ;仅当属性没有找到时调用 C._setattr_(self, attr, val) 设置属性 C._delattr_(self, attr) 删除属性 C._getattribute_(self, attr) a 获取属性;内建 getattr();总是被调用 C._get_(self, attr) a (描述符)获取属性 C._set_(self, attr, va

32、l) a (描述符)设置属性 C._delete_(self, attr) a (描述符)删除属性 软件编程思想 C._*add_(self, obj) 加;+操作符 C._*sub_(self, obj) 减;-操作符 C._*mul_(self, obj) 乘;*操作符 C._*div_(self, obj) 除;/操作符 C._*truediv_(self, obj) 除;/操作符 C._*floordiv_(self, obj) Floor 除; C._*mod_(self, obj) 取模/取余;%操作符 C._*divmod_(self, obj) 除和取模;内建divmod()

33、C._*pow_(self, obj, mod) 乘幂;内建pow();*操 作符 C._*lshift_(self, obj) 左移位;操作符 C._*and_(self, obj) 按位与;内建int() C._long_(self) 转为long;内建long() C._float_(self) 转为float;内建float() 数值类型:基本表示法(String) C._oct_(self) 八进制表示;内建oct() C._hex_(self) 十六进制表示;内建hex() C._coerce_(self, num) 压缩成同样的数值类型;内 建coerce() C._index_

34、(self)g 在有必要时,压缩可选的数值类型 为整型(比如:用于切片索引等等) 软件编程思想 简单定制 class RoundFloatManual(object): def _init_(self, val): assert isinstance(val, float),“must be a float! self.value = round(val, 2) rfm = RoundFloatManual(4.2) print rfm def _str_(self): return str(self.value) print rfm 4.2 软件编程思想 class Time60(objec

35、t): # ordered pair def _init_(self, hr, min): self.hr = hr # assign hours self.min = min # assign minutes def _str_(self): return %d:%d % (self.hr, self.min) def _add_(self, other): return self._class_(self.hr + other.hr, self.min + other.min) mon = Time60(10, 30) tue = Time60(11, 15) print mon+tue

36、21:45 软件编程思想 def _iadd_(self, other): self.hr += other.hr self.min += other.min return self mon =Time60(10,30) tue =Time60(11,15) id(mon) 401872 mon += tue id(mon) 401872 mon 21:45 软件编程思想 v 迭代器(RandSeq 和AnyIter) from randseq import RandSeq for eachItem in RandSeq( . (rock, paper, scissors): . print

37、eachItem Scissors scissors rock paper paper scissors 软件编程思想 class AnyIter(object):class AnyIter(object): def _init_(self, data, safe=False): def _init_(self, data, safe=False): self.safe = safe self.iter = iter(data) def _iter_(self): def _iter_(self): return self return self def next(self, howmany=

38、1): def next(self, howmany=1): retval = for eachItem in range(howmany): for eachItem in range(howmany): try: try: retval.append(self.iter.next() except StopIteration: except StopIteration: if self.safe:if self.safe: breakbreak else:else: raiseraise return retval return retval a = AnyIter(range(10) i

39、 = iter(a) for j in range(1,5): print j, :, i.next(j) 1 : 0 2 : 1, 2 3 : 3, 4, 5 4 : 6, 7, 8, 9 软件编程思想 *多类型定制(NumStr) 类NumStr,数字-字符对n:s 加: NumStr1+NumStr2 表示n1+n2:s1+s2 乘: NumStr1*NumStr2=n1*n:s1*n 比较: (n1n2) 且 (s1s2)时,返回 1, (n1n2)且(s1s2)时,返回-1, 数值和字符串都一样时,或是两个比较的结果正相反时( 即(n1s2),或相反),返回0 软件编程思想 clas

40、s NumStr(object): def _init_(self, num=0, string=): self._num = num self._string = string def _str_(self): # define for str() return %d : %r % self._num, self._string) _repr_ = _str_ def _nonzero_(self): # False if both are return self._num or len(self._string) def _norm_cval(self, cmpres):# normali

41、ze cmp() return cmp(cmpres, 0) def _cmp_(self, other): # define for cmp() return self._norm_cval(cmp(self._num, other._num) + self._norm_cval(cmp(self._string, other._string) 软件编程思想 class NumStr(object): def _add_(self, other): # define for s+o if isinstance(other, NumStr): return self._class_(self.

42、_num +other._num,self._string + other._string) else: raise TypeError, Illegal for built-in operation def _mul_(self, num): # define for o*n if isinstance(num, int): return self._class_(self._num * num, self._string * num) else: raise TypeError, Illegal for built-in operation 软件编程思想 私有化 1.只提供访问函数来访问其

43、值,实现隐藏 2.由双下划线开始的属性在运行时被“混淆”, 直接访问是不允许的 3.self._num 属性为例,用于访问这个数据值 的标识就变成了self._NumStr_num。 4.可以防止在祖先类或子孙类中的同名冲突。在 类中有一个_XXX 属性,它将不会被其子类中的 _XXX 属性覆盖 软件编程思想 授权 包装:对一个已存在的对象进行包装,不管它是 数据类型,还是一段代码,可以是对一个已存在 的对象,增加新的,删除不要的,或者修改其它 已存在的功能。 软件编程思想 实现授权 授权的过程,即是所有更新的功能都是由新类的 某部分来处理,但已存在的功能就授权给对象的 默认属性。 软件编程思

44、想 class WrapMe(object): def _init_(self, obj): self._data = obj def get(self): return self._data def _repr_(self): return self._data def _str_(self): return str(self._data) def _getattr_(self, attr): return getattr(self._data, attr) wrappedComplex = WrapMe(3.5+4.2j) wrappedComplex 3.5+4.2j wrappedCo

45、mplex.real 3.5 wrappedComplex.imag 4.2 wrappedComplex.conjugate() (3.5-4.2j) wrappedComplex.get() (3.5+4.2j) wrappedList = WrapMe(123, foo, 45.67) wrappedList.append(bar) wrappedList 123, foo, 45.67, bar wrappedList.index(45.67) 2 软件编程思想 f = WrapMe(open(/etc/motd) f.get() f.readline() Have a lot of

46、fun.012 f.tell() 21 class WrapMe(object): def _init_(self, obj): self._data = obj def get(self): return self._data def _repr_(self): return self._data def _str_(self): return str(self._data) def _getattr_(self, attr): return getattr(self._data, attr) 软件编程思想 from time import time, ctime class TimedWr

47、apMe(object): def _init_(self, obj): self._data = obj self._ctime = self._mtime = self._atime = time() def gettimeval(self, t_type): if not isinstance(t_type, str) or t_type0 not in cma: raise TypeError,argument ofc,m,or areqd return getattr(self, _%s_%stime % (self._class_._name_, t_type0) def gettimestr(self, t_type): return ctime(self.gettimeval(t_type) def _getattr_(self, attr): # delegate self._atime = time() return getattr(self._data, attr) 软件编程思想 def _repr_(self): # repr() self._atime = time() return self._data timeWrappedO

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论