




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第6章面向对象程序设计学习目标
掌握类与对象编程方法
了解类中各类数据成员和方法成员的使用
掌握继承和多态
了解常用特殊方法22025/3/66.1类与对象
对象(Object)表示现实世界中的特定实体类是Python语言的核心,在Python中各种数据类型都是类,而对象则是实例化和具体化的类。32025/3/66.1.1创建类和对象定义一个类:Python使用class关键字来定义类,class关键字之后是一个空格,然后是类的名字,再然后是一个冒号,最后换行并定义类的内部实现。
类名首字母一般采取大写的方式,但也可根据需要自行设定命名规范。42025/3/6>>>classCar: defgetInfo(self): print('Thisisacar')6.1.1创建类和对象实例化对象
在类名后添加一个括号用于实例化该类。
通过“对象名.成员”的方式来访问其中的成员属性或成员方法。52025/3/6>>>car=Car()>>>car.getInfo()Thisisacar>>>isinstance(car,Car)True>>>isinstance(car,tuple)False6.1.2构造方法
类中的函数称为该类的方法,其中__ini()__,开头和结尾各有一对下划线,称为构造方法,在实例化类的时候被自动调用。62025/3/6>>>classCar: def__init__(self,color,model): print('Thecoloris%sandthemodelis%s'%(color,model))
defgetInfo(self): print('Thisisacar')
>>>a=Car('red','audi')Thecolorisredandthemodelisaudi6.1.3实例成员
一个实例化对象的成员是指它的数据和方法。
实例的数据保存在该实例的成员变量中,用于表示该实例的属性。
对于一个实例化对象,可以使用圆点运算符“.”来使用其成员变量和成员方法,又称对象访问,使用形式为“对象名.实例成员”。72025/3/66.1.3实例成员getInfo(self)方法就是一个实例方法,实例方法具有如下性质:
实例方法在定义时一般将self作为第一个输入参数。
实例方法可以在该类的其它实例方法中调用,具体方法为“self.实例方法名(参数)”。
实例方法可以在类的实例化对象中进行访问,具体形式为“对象名.实例方法名(参数)”。82025/3/66.1.3实例成员
在实例方法中定义的实例变量,在定义时以self作为前缀。实例变量具有以下性质:
实例变量在类的实例方法中定义,定义时以“self.实例变量名”的形式。实例变量可以在类的实例化对象中进行访问,访问时的形式为“对象名.实例变量名”。实例变量可以在其所在类的实例方法中进行访问,但必须保证访问之前已经对该实例变量进行。初值的设定,一般应在构造方法中初始化各种实例变量。92025/3/6【例6-1】定义和使用一个汽车类102025/3/6classCar:def__init__(self,color,model):self.color=color
self.setModel(model)
=''
defgetInfo(self):msg='Thecoloris'+self.color+'andthemodelis'+self.modelmsg+=',thenameis'+print(msg)
defsetPrice(self):
pass
defsetName(self,name):=name
defsetModel(self,model):self.model=model6.1.3实例成员112025/3/6>>>a=Car('red','audi') >>>a.getInfo() Thecolorisredandthemodelisaudi,thenameis>>>print(a.color)red>>>print(a.model)audi>>>a.setName('Babi')>>>a.color='blue'>>>a.model='bmw'>>>a.getInfo()Thecolorisblueandthemodelisbmw,thenameisBabi6.2封装
封装(Encapsulation)是面向对象的主要特征,是把客观事物抽象并封装成对象,将数据成员、方法等集合在一个整体内。
完成封装的对象,可以实现信息的隐藏,只允许可信的对象访问和操作隐藏的内部数据,而其公有数据则不受这种限制。
采用封装思想所建立的类实现了数据和方法的统一管理,使用者无需关心方法在类内部的具体实现,只需要直接使用类的方法。122025/3/66.2.1类的数据成员
类的数据成员是类固有的特征,代表了一类对象的公共性质。
类的数据成员根据其特点可以分为两种,一种是为类建立的数据成员,它是在所有方法之外所定义的属性,即类属性,从变量的角度看这种变量叫做类变量。
类变量属于整个类,不是某个实例的一部分,而是所有实例之间共享的公共属性。对类变量的引用一般采用“类名.类变量名”的方式。132025/3/66.2.1类的数据成员
另一种是在实例方法中定义的成员属性,在定义时以self作为前缀,即实例变量,一般要求在类的实例对象中引用。142025/3/6>>>classStudent:course=''
def__init__(self,name,age):=name
self.age=age
>>>a=Student('Zhang',20)>>>b=Student('Wang',21)>>>Student.course='math'>>>print(,a.age,Student.course)Zhang20math>>>print(,b.age,b.math)Wang21math6.2.2类的方法成员
类的方法成员包括实例方法、类方法和静态方法三种类型。实例方法实例方法的第一个参数为self,可以引用类的实例变量,但它不能引用类变量。要实现对类变量的引用,就需要采用类方法。152025/3/66.2.2类的方法成员类方法
类本身的方法就是类方法。类方法不对特定实例进行操作,在类方法中也不能访问实例变量。
类方法通过修饰符@classmethod来定义,方法的第一个形式参数一般需要设置为cls。162025/3/6@classmethoddefshowCourse(cls):print('Thecourseis',cls.course)6.2.2类的方法成员
类方法一般需要类名来访问,也可以通过对象实例来调用。172025/3/6>>>a=Student('Zhang',20)>>>Student.course='math'>>>a.showCourse()Thecourseismath>>>Student.showCourse()Thecourseismath6.2.2类的方法成员静态方法
Python允许在类中声明与类的对象实例无关的方法,称为静态方法。
静态方法只是名义上归属类管理,并不能使用类变量和实例变量。
在声明时,静态方法需要采用修饰符@staticmethod加以说明。
静态方法一般采用类名来引用,也可以利用实例对象名来引用静态方法。182025/3/6【例6-2】定义和使用一个学生类192025/3/6classStudent:course=''
def__init__(self,name,age):=nameself.age=age
@classmethod#类方法defshowCourse(cls):print('Thecourseis',cls.course)print(cls.getAverage(4,5,6),Student.getAverage(4,5,6))
defsetScore(self,score):self.score=score
@staticmethod#静态方法defgetAverage(a,b,c):return(a+b+c)/3
【例6-2】定义和使用一个学生类202025/3/6程序的运行结果如下:Thecourseismath5.05.070.0Intest():mathThecourseismath5.05.02.0deftest(self):print('Intest():',Student.course)Student.showCourse()print(Student.getAverage(1,2,3))
a=Student('Zhang',20)b=Student('Wang',21)Student.course='math'a.showCourse()print(a.getAverage(60,70,80))a.test()6.2.3访问控制Python中一般的成员变量和成员方法都是公有成员,没有特殊的访问限制,可以直接用实例对象名加圆点运算符的形式对成员进行引用。Python采取变量名称约定的方式实现访问控制,类的成员一般为公有成员,如果名称的首部有下划线,就会改变其访问限制属性。212025/3/66.2.3访问控制222025/3/6
以单下划线开始的成员为保护成员,形式如_var,只有类实例和子类实例能访问到这些成员,不能用‘frommoduleimport*’导入的方式来访问。
以双下划线开始的成员是私有成员,形式如__var,意思是只能在类内部的方法中使用,即便是子类的方法也不能访问到这个成员。
Python中一般的成员变量和成员方法都是公有成员,没有特殊的访问限制,可以直接用实例对象名加圆点运算符的形式对成员进行引用。【例6-3】定义和使用一个人员类232025/3/6classPerson:def__init__(self,name,age):=nameself.age=ageself._career=''
self.__money=0 defintroduce(self):print("我的名字{},年龄{}".format(,self.age))defgetMoney(self):returnself.__moneydefsetMoney(self,money):self.__money=moneydef_buy(self,cost):if(self.__evaluate(cost)): 【例6-3】定义和使用一个人员类242025/3/6print('完成购买')returnprint('无法购买')
def__evaluate(self,cost):if(cost>self.__money):
returnFalseself.__money-=costreturnTrue【例6-3】定义和使用一个人员类252025/3/6>>>a=Person(name='张三',age=20)>>>roduce() 我的名字张三,年龄20>>>a._career='会计'
>>>a.setMoney(100)>>>print(a._career)会计>>>a._buy(5)
完成购买>>>print(a.getMoney())956.2.4属性
一个成员变量设置为公有,可以直接读取、修改该变量。
私有成员变量可以设置getter和setter的方法,实现对私有成员变量的使用。
为私有成员变量设置只读、修改或删除属性,可达到对私有成员变量进行相应操作的目的。
可以通过为方法添加@property修饰符来声明属性的只读权限,利用@属性名.setter来修饰可修改权限,通过@属性名.deleter来修饰属性的可删除权限。
不设置可删除权限的修饰符及其相关方法,则原有变量会默认具有不可删除的权限。262025/3/6【例6-4】定义和使用一个用于演示类访问控制的人员类272025/3/6classPerson:def__init__(self,name,age):=nameself.age=ageself._career=''
self.__money=0 defintroduce(self):print("我的名字{},年龄{}".format(,self.age))
@property
defmoney(self):returnself.__money【例6-4】定义和使用一个用于演示类访问控制的人员类282025/3/6@money.setter
defmoney(self,money):self.__money=money
def_buy(self,cost):if(self.__evaluate(cost)):print('完成购买')returnprint('无法购买')
def__evaluate(self,cost):if(cost>self.__money):returnFalseself.__money-=costreturnTruea=Person(name='张三',age=20) #类的实例化roduce()a._career='会计' a.money=50print(a.money)print(a._career)a._buy(5)print(a.money)【例6-4】定义和使用一个用于演示类访问控制的人员类
要增加可删除属性,可在类中添加以下代码。
用于定义属性的另一种方法是采用property_name=property(fget=get_name,fset=
set_name,fdel=del_name,doc='')
函数的方案,这一方法无需设置属性的修饰符,只需在property()函数中声明属性的各个权限所对应的方法,若不需要设置该权限可以将方法设置为None。292025/3/6
@money.deleter defmoney(self):delself.__money6.2.5动态成员绑定
对象的成员方法一般在其类的设计时直接建立。
在某些情况下,可能会需要在运行时为对象动态添加成员,这使得类的实现更加灵活,也比较符合现实世界中对象的属性和活动可能随着时间改变的特性。302025/3/6【例6-5】用于演示采用类的动态成员方法绑定的汽车类312025/3/6classCar:def__init__(self,color,model):self._color=color
self.model=modelself.__name=''defgetInfo(self):msg='Thecoloris'+self._color+'andthemodelis'+self.modelmsg+=',thenameis'+self.__nameprint(msg)defsetName(self,name):self.__name=nameimporttypesdefsetSpeed(self,speed):self.speed=speed【例6-5】用于演示采用类的动态成员方法绑定的汽车类322025/3/6print(a.speed)#print(c.speed) #会报错误信息AttributeError:'Car'objecthasnoattribute'speed'b.setSpeed=types.MethodType(setSpeed,Car)b.setSpeed(60)print(b.speed)print(c.speed) #因绑定了类,此处工作正常程序运行结果如下:606060a=Car('red','audi')b=Car('blue','bmw')c=Car('yellow','benz')a.setSpeed=types.MethodType(setSpeed,a)a.setSpeed(60)6.2.5动态成员绑定332025/3/6>>>a.length=5 #为实例a动态添加一个车体长度length的实例变量>>>print(a.length)5>>>print(b.length) #实例b并不具备新添加的length属性AttributeError:'Car'objecthasnoattribute'length'>>>Car.seat=5 #添加了一个类属性>>>print(c.seat) #能够访问类变属性56.2.5动态成员绑定342025/3/6>>>print(a._color) #可以访问保护成员变量red>>>print(a.__name) #无法访问私有成员变量AttributeError:'Car'objecthasnoattribute'__name'>>>a.setName('Babi')>>>a.getInfo()Thecolorisredandthemodelisaudi,thenameisBabi>>>a.__name='gimi' #直接设置a.__name成功执行>>>print(a.__name)gimi>>>a.getInfo()Thecolorisredandthemodelisaudi,thenameisBabi >>>print(b.__name)AttributeError:'Car'objecthasnoattribute'__name'6.3继承和多态继承和多态是面向对象程序设计的重要特性,它们为代码复用和程序的功能完善及对多样本数据的处理提供了可能。352025/3/66.3.1继承
面向对象的一个重要特征就是继承,它允许一个类继承另一个已有的设计良好的类中的成员来充实自己的功能,同时子类也可以对这些功能进行二次开发,从而减少开发的工作量。
在继承关系中,已有的、设计好的类称为父类或基类,新设计的类称为子类或派生类。派生类可以继承父类的公有成员,但是不能继承其私有成员。362025/3/66.3.1继承object类是所有类的基类,如果要进行类的继承,其基类应声明为“基类名(object)”的形式,而子类则声明为“子类名(基类名)”的形式,表示其继承了该基类。
类可以有一个或多个父类,并从它们那里继承行为。对类B的实例调用方法或访问其属性时,如果找不到该方法或属性,将在其父类A中查找。
若子类定义的成员方法具有与父类相同的名字,即构成方法重写的条件。372025/3/66.3.1继承382025/3/6>>>classA: defhello(self): print("Hello,I'mA.") defplay(self): print('Ilikeplayingfootball')>>>classB(A):pass>>>b=B()>>>b.hello()Hello,I'mA.>>>classC(A): defhello(self,msg): print("Hello,I'mC.",msg)>>>c=C()>>>c.hello() TypeError:hello()missing1requiredpositionalargument:'msg'>>>c.hello('welcome') Hello,I'mC.welcome>>>c.play()Ilikeplayingfootball6.3.1继承
子类的构造函数中应有调用父类构造函数的方法
super().__init__(参数列表)父类名.__init__(
self,参数列表)392025/3/6【例6-6】一个继承于人员类的教师类402025/3/6classPerson(object):def__init__(self,name='',age=20,sex='man'):self.setName(name)self.setAge(age)self.setSex(sex)print('Person',self.__name,'initialized')defsetName(self,name):if(notisinstance(name,str)):print('namemustbestring.')self.__name=namedefsetAge(self,age):if(notisinstance(age,int)):print('agemustbeinteger.')self.__age=agedefsetSex(self,sex):if(notsexin('man','woman')):print('sexmustbe"man"or"woman"')self.__sex=''returnself.__sex=sexdefshow(self):print('Name:',self.__name)print('Age:',self.__age)print('Sex:',self.__sex)【例6-6】一个继承于人员类的教师类412025/3/6classTeacher(Person):#派生类def__init__(self,name='',age=30,sex='man',department='Computer'):super().__init__(name,age,sex)#也可以使用下面的形式对基类数据成员进行初始化#Person.__init__(self,name,age,sex)self.setDepartment(department)
defsetDepartment(self,department):self.__department=department
defshow(self):super().show()print('Department:',self.__department)
【例6-6】一个继承于人员类的教师类422025/3/6if__name__=='__main__': print('='*30)p=Person('ZhangSan',19,'man')p.show()print('='*30)t=Teacher('LiSi',32,'man','Math')t.show()程序运行结果如下:==============================sexmustbe"man"or"woman"PersonZhangSaninitializedName:ZhangSanAge:19Sex:==============================PersonLiSiinitializedName:LiSiAge:32Sex:manDepartment:Math6.3.2多态
多态(Polymorphism),意思是多种样式,在继承关系中引入多态,使得Python可以在运行时根据引用实例的不同而执行不同的行为,调用对应的方法。
多态往往会对应于一个统一的接口,但由于传入的类型不同而产生不同的执行效果。
432025/3/6【例6-7】动物吠叫的多态实现方法示例442025/3/6classAnimal(object):def__init__(self,name):=nameprint('%sinitialized'%)
defbark(self): print(,'叫')defanimal_bark(obj):
obj.bark()classCat(Animal):def__init__(self,name):super().__init__(name)【例6-7】一个继承于人员类的教师类452025/3/6defbark(self):print('%s:喵喵喵!'%)classDog(Animal):
defbark(self):print('%s:汪!汪!汪!'%)
deffunc(animal):
animal.bark()
a=Cat('cat')b=Dog('dog')c=Animal('animal')func(a)func(b)func(c)程序运行结果如下:catinitializeddoginitializedanimalinitializedcat:喵喵喵!dog:汪!汪!汪!animal叫6.4.1常用特殊方法Python类有大量的特殊方法,比较常见的是构造函数和析构函数,除此之外,运算符重载就是通过重写特殊方法实现的。Python中类的构造函数是__init__(),一般用来为数据成员设置初值或进行其他必要的初始化工作,在创建对象时被自动调用和执行。
Python中类的析构函数是__del__(),一般用来释放对象占用的资源,在Python删除对象和收回对象空间时被自动调用和执行。462025/3/66.4.1常用特殊方法472025/3/66.4.2运算符重载
运算符重载是让自定义的类所生成的对象(实例)能够使用常规运算符进行操作。
要实现运算符重载需要具备两个条件,一是找出想要重载的常规运算符,二是找出该运算符所对应的特殊方法名称。
以加号的重载为例,加号所对应的方法__add__(),经常在实际使用中被重新定义,用来重载一般意义上的“+”号。482025/3/6【例6-8】一个自定义的数组492025/3/6classNumArray:'Auser-definedarrayofnumbers(int,float,complex)'def__IsNumber(self,n):returnisinstance(n,(int,float,complex))
def__init__(self,*args):ifnotargs:
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 天津市双菱中学2024-2025学年高二上学期期中考试化学试题(含答案)
- 广东省揭阳新华中学2024-2025学年高一下学期第一次月考化学试卷(含答案)
- 2024-2025学年河北省张家口市怀安县八年级(上)期末物理试卷(含答案)
- 2019-2025年军队文职人员招聘之军队文职法学题库综合试卷A卷附答案
- 餐饮厨房考试试题及答案
- 配对合同范本(2篇)
- 2025年度施工员(市政工程)专业技能知识考试题库及答案(一)
- 口腔牙周病知识培训课件
- 化学基本知识培训课件
- 私人酒窖租赁服务酒品保管免责
- 2025年中考百日誓师活动教师代表发言(三)
- 中国家用通风电器具制造行业分析报告
- 生物-天一大联考2025届高三四省联考(陕晋青宁)试题和解析
- 天津2025年天津市住房公积金管理中心招聘9人笔试历年参考题库附带答案详解-1
- 区间价格突破策略(TB版)
- 高中主题班会 远离背后“蛐蛐”课件-高二下学期人际交往主题班会
- 2024广西公务员考试及答案(笔试、申论A、B类、行测)4套 真题
- 2024年山东省济南市中考英语试题卷(含答案解析)
- 汽车坡道玻璃雨棚施工方案
- 新高考英语读后续写——人物描写高级表达素材
- EN10204-2004中文版
评论
0/150
提交评论