您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > Python面向对象程序设计
第6章面向对象程序设计面向对象程序设计(ObjectOrientedProgramming,OOP)的思想主要针对大型软件设计而提出,使得软件设计更加灵活,能够很好地支持代码复用和设计复用,并且使得代码具有更好的可读性和可扩展性。面向对象程序设计的一条基本原则是计算机程序由多个能够起到子程序作用的单元或对象组合而成,这大大地降低了软件开发的难度,使得编程就像搭积木一样简单。面向对象程序设计的一个关键性观念是将数据以及对数据的操作封装在一起,组成一个相互依存、不可分割的整体,即对象。对于相同类型的对象进行分类、抽象后,得出共同的特征而形成了类,面向对象程序设计的关键就是如何合理地定义和组织这些类以及类之间的关系。Python完全采用了面向对象程序设计的思想,是真正面向对象的高级动态编程语言,完全支持面向对象的基本功能,如封装、继承、多态以及对基类方法的覆盖或重写。但与其他面向对象程序设计语言不同的是,Python中对象的概念很广泛,Python中的一切内容都可以称为对象例如,字符串、列表、字典、元组等内置数据类型都具有和类完全相似的语法和用法。创建类时用变量形式表示的对象属性称为数据成员或成员属性,用函数形式表示的对象行为称为成员函数或成员方法,成员属性和成员方法统称为类的成员。6.1.1类定义语法Python使用class关键字来定义类,class关键字之后是一个空格,然后是类的名字,再然后是一个冒号,最后换行并定义类的内部实现。类名的首字母一般要大写,当然您也可以按照自己的习惯定义类名,但是一般推荐参考惯例来命名,并在整个系统的设计和实现中保持风格一致,这一点对于团队合作尤其重要。例如:classCar:#新式类必须有至少一个基类definfor(self):print(Thisisacar)6.1.1类定义语法定义了类之后,可以用来实例化对象,并通过“对象名.成员”的方式来访问其中的数据成员或成员方法,例如下面的代码:car=Car()car.infor()Thisisacar在Python中,可以使用内置方法isinstance()来测试一个对象是否为某个类的实例,下面的代码演示了isinstance()的用法。isinstance(car,Car)Trueisinstance(car,str)False6.1.1类定义语法最后,Python提供了一个关键字“pass”,类似于空语句,可以用在类和函数的定义中或者选择结构中。当暂时没有确定如何实现功能,或者为以后的软件升级预留空间,或者其他类型功能时,可以使用该关键字来“占位”。例如下面的代码都是合法:classA:passdefdemo():passif53:pass6.1.2self参数类的所有实例方法都必须至少有一个名为“self”的参数,并且必须是方法的第一个形参(如果有多个形参的话),“self”参数代表将来要创建的对象本身。在类的实例方法中访问实例属性时需要以“self”为前缀,但在外部通过对象名调用对象方法时并不需要传递这个参数,如果在外部通过类名调用对象方法则需要显式为self参数传值。6.1.2self参数在Python中,在类中定义实例方法时将第一个参数定义为“self”只是一个习惯,而实际上类的实例方法中第一个参数的名字是可以变化的,而不必须使用“self”这个名字,例如下面的代码:classA:def__init__(hahaha,v):hahaha.value=vdefshow(hahaha):print(hahaha.value)a=A(3)a.show()36.1.3类成员与实例成员这里主要指数据成员,或者广义上的属性。可以说属性有两种,一种是实例属性,另一种是类属性。实例属性一般是指在构造函数__init__()中定义的,定义和使用时必须以self作为前缀;类属性是在类中所有方法之外定义的数据成员。在主程序中(或类的外部),实例属性属于实例(对象),只能通过对象名访问;而类属性属于类,可以通过类名或对象名访问。6.1.3类成员与实例成员在类的方法中可以调用类本身的其他方法,也可以访问类属性以及对象属性。在Python中比较特殊的是,可以动态地为类和对象增加成员,这一点是和很多面向对象程序设计语言不同的,也是Python动态类型特点的一种重要体现。6.1.3类成员与实例成员classCar:price=100000#定义类属性def__init__(self,c):self.color=c#定义实例属性car1=Car(Red)car2=Car(Blue)print(car1.color,Car.price)Car.price=110000#修改类属性Car.name='QQ'#增加类属性car1.color=Yellow#修改实例属性print(car2.color,Car.price,Car.name)print(car1.color,Car.price,Car.name)defsetSpeed(self,s):self.speed=scar1.setSpeed=types.MethodType(setSpeed,Car)#动态为对象增加成员方法car1.setSpeed(50)#调用对象的成员方法print(car1.speed)6.1.3类成员与实例成员在Python中,函数和方法是有区别的。方法一般指与特定实例绑定的函数,通过对象调用方法时,对象本身将被作为第一个参数传递过去,普通函数并不具备这个特点。classDemo:passt=Demo()deftest(self,v):self.value=vt.test=testt.testfunctiontestat0x00000000034B7EA0t.test(t,3)print(t.value)3t.test=types.MethodType(test,t)t.testboundmethodtestof__main__.Demoobjectat0x000000000074F9E8t.test(5)print(t.value)56.1.4私有成员与公有成员Python并没有对私有成员提供严格的访问保护机制。在定义类的属性时,如果属性名以两个下划线“__”开头则表示是私有属性,否则是公有属性。私有属性在类的外部不能直接访问,需要通过调用对象的公有成员方法来访问,或者通过Python支持的特殊方式来访问。Python提供了访问私有属性的特殊方式,可用于程序的测试和调试,对于成员方法也具有同样的性质。私有属性是为了数据封装和保密而设的属性,一般只能在类的成员方法(类的内部)中使用访问,虽然Python支持一种特殊的方式来从外部直接访问类的私有成员,但是并不推荐您这样做。公有属性是可以公开使用的,既可以在类的内部进行访问,也可以在外部程序中使用。6.1.4私有成员与公有成员classA:def__init__(self,value1=0,value2=0):self._value1=value1self.__value2=value2defsetValue(self,value1,value2):self._value1=value1self.__value2=value2defshow(self):print(self._value1)print(self.__value2)a=A()a._value10a._A__value2#在外部访问对象的私有数据成员06.1.4私有成员与公有成员在IDLE环境中,在对象或类名后面加上一个圆点“.”,稍等一秒钟则会自动列出其所有公开成员,模块也具有同样的特点。而如果在圆点“.”后面再加一个下划线,则会列出该对象或类的所有成员,包括私有成员。6.1.4私有成员与公有成员在Python中,以下划线开头的变量名和方法名有特殊的含义,尤其是在类的定义中。用下划线作为变量名和方法名前缀和后缀来表示类的特殊成员:_xxx:这样的对象叫做保护成员,不能用'frommoduleimport*'导入,只有类对象和子类对象能访问这些成员;__xxx__:系统定义的特殊成员;__xxx:类中的私有成员,只有类对象自己能访问,子类对象也不能访问到这个成员,但在对象外部可以通过“对象名._类名__xxx”这样的特殊方式来访问。Python中不存在严格意义上的私有成员。6.1.4私有成员与公有成员另外,在IDLE交互模式下,一个下划线“_”表示解释器中最后一次显示的内容或最后一次语句正确执行的输出结果。例如:3+58_+210_*330_/56331/0Traceback(mostrecentcalllast):Filepyshell#2,line1,inmodule1/0ZeroDivisionError:integerdivisionormodulobyzero_36.1.4私有成员与公有成员classFruit:def__init__(self):self.__color='Red'self.price=1apple=Fruit()apple.price#显示对象公开数据成员的值1apple.price=2#修改对象公开数据成员的值apple.price2print(apple.price,apple._Fruit__color)#显示对象私有数据成员的值2Redapple._Fruit__color=Blue#修改对象私有数据成员的值print(apple.price,apple._Fruit__color)2Blueprint(apple.__color)#不能直接访问对象的私有数据成员,出错AttributeError:Fruitinstancehasnoattribute'__color'6.2方法在类中定义的方法可以粗略分为四大类:公有方法、私有方法、静态方法和类方法。其中,公有方法、私有方法都属于对象,私有方法的名字以两个下划线“__”开始,每个对象都有自己的公有方法和私有方法,在这两类方法中可以访问属于类和对象的成员;公有方法通过对象名直接调用,私有方法不能通过对象名直接调用,只能在属于对象的方法中通过“self”调用或在外部通过Python支持的特殊方式来调用。如果通过类名来调用属于对象的公有方法,需要显式为该方法的“self”参数传递一个对象名,用来明确指定访问哪个对象的数据成员。静态方法和类方法都可以通过类名和对象名调用,但不能直接访问属于对象的成员,只能访问属于类的成员。一般将“cls”作为类方法的第一个参数名称,但也可以使用其他的名字作为参数,并且在调用类方法时不需要为该参数传递值。6.2方法6.2方法r=Root(3)r.classShowTotal()#通过对象来调用类方法1r.staticShowTotal()#通过对象来调用静态方法1r.show()self.__value:3Root.__total:1rr=Root(5)Root.classShowTotal()#通过类名调用类方法2Root.staticShowTotal()#通过类名调用静态方法26.2方法Root.show()#试图通过类名直接调用实例方法,失败TypeError:unboundmethodshow()mustbecalledwithRootinstanceasfirstargument(gotnothinginstead)Root.show(r)#但是可以通过这种方法来调用方法并访问实例成员self.__value:3Root.__total:2r.show()self.__value:3Root.__total:2
本文标题:Python面向对象程序设计
链接地址:https://www.777doc.com/doc-5050609 .html