版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第5讲面向对象程序设计方法第4讲主讲内容2类及基本使用31面向对象程序设计4类的封装、继承与多态5类使用常用案例类方法及调用方式
Python是完全面向对象的语言,面向对象的本质是把数据和处理数据的过程当成一个整体--对象。从一般意义上讲,对象是现实世界中一个实际存在的事物,比如一辆汽车、人、一个动物等。对象是构成世界的一个独立单位,它具有自己的静态特征(状态)和动态特征(操作)。静态特征即可以用某种数据来描述的特征,动态特征即对象所表现的行为或对象所具有的功能。对象也是通过类定义的数据结构实例。对象变量包括类变量和实例变量。 面向对象语言把状态和操作封装于对象体之中,并提供一种访问机制,使对象的“私有数据”仅能由这个对象的操作来执行。用户只能通过允许公开的操作提出要求,查询和修改对象的状态。1、对象的概念一、面向对象技术简介
对象的示例收银员对象顾客对象顾客姓名:朱丽叶年龄:28体重:52千克操作:购买商品状态姓名:布兰尼职衔:收银员年龄:35体重:60千克操作:收款打印帐单行为面向对象的三大特征:封装、继承和多态(1)封装:属性和方法放到类内部,通过对象访问属性或者方法,隐藏功能的实现细节.当然还可以设置访问权限;它的意义是:将属性和方法放到一起做为一个整体,然后通过实例化对象来处理;隐藏内部实现细节,只需要和实现对象及其属性和方法交互;对类的属性和方法增加访问权限控制。(2)继承:子类需要复用父类里面的属性或者方法,当然子类还可以提供自己的属性和方法;其意义是:主要体现是实现代码的重用,相同的代码不需要重复的编写;子类可以在父类功能上进行重写,扩展类的功能。当已经创建了一个类,需要创建一个与之相似的类,添加/删除/修改其中的几个方法,可以从原来的类派生出一个新的类,把原来的类称为父2、面向对象的特征类或基类,而派生出的类称为子类或派生类,子类继承了父类的所有数据和方法。(3)多态:指在父类中定义的属性和方法被子类继承之后,可以具有不同的数据类型或表现出不同的行为,这使得同一个属性或方法在父类及其各个子类中具有不同的含义。多态的好处:在保证安全性的前提下,提高了方法调用的灵活性。多态的实现:定义一个父类定义多个子类,并重写父类的方法传递子类对象给调用者,不同子类对象能产生不同执行效果二、类及基本使用类以共同特性和操作定义实体类是用于组合各个对象所共有操作和属性的一种机制,例如:1、什么是类(Class):
类是用来描述具有相同属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。类的示例动物类交通类图形类人类动物类2、类和对象的示例对象(1)类与对象类和对象的示例人类收银员系统管理员仓库管理员促销员采购经理人类实例化:创建一个类的实例,类的具体对象。(2)类和对象的区别类是概念模型,定义对象的所有特性和所需的操作对象是类的实例类定义实体对象是实际的实体所有属于同一个类的对象都具有相同的特性和操作类和对象类是对象的原型类是对具有共同属性和行为的对象的抽象类是对象的模板(template)对象是类的一个实例(instance),或对象是具有具体属性和行为的实体类抽象实例化对象行为或操作属性或状态类方法类变量类变量或者实例变量,用于处理类及其实例对象的相关的数据。以双下划线"__"开头和结尾命名的成员方法,都被称为类的特殊成员,例如,类的__init__(self)构造方法就是典型的特殊方法。属性是包含对象变量的信息(数字、字符串等)行为是完成某个工作的代码块。方法可以是对象中的函数,包括传递参数和返回值。例如,教师类的实例化:3、类的层次结构交通类图形类4、属性事物的特性在类中表示为成员变量每个对象都拥有属性值,例如:学号姓名属性年龄学生对象在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。在类中表示对象或实体拥有的特性称为属性
class
Student:
pass
t=Student()
=‘张三'
Python中的属性是普通方法的衍生,操作类属性有三种方法:(1)使用@property装饰器操作类属性。
装饰器可以实现获取,设置,删除隐藏的属性,通过装饰器可以对属性的取值和赋值加以控制,提高代码的稳定性。(2)使用类或实例直接操作类属性(例如:,obj.age=18,delobj.age)(3)使用Python内置函数操作属性。类的私有属性__private_attrs:两个下划线开头,声明该属性为私有,不能在类地外部被使用或直接访问。在类内部的方法中使用时self.__private_attrs5、方法的概念操作的实际实现如何执行所请求的操作的规范方法指定操作对象数据的方式在得到操作请求时指定如何做的算法在类中定义的方法可以粗略分为四大类:公有方法、私有方法、静态方法、类方法。公有方法、私有方法一般所指属于对象的实例方法,私有方法的名字以两个下划线__开始。(1)什么是方法方法:类中定义的函数。(2)方法的示例缝衣服的步骤量尺寸得到工具缝衣服方法缝制衣服裁缝6、类的定义格式class类名(基类):类变量def函数名1(self,参数类别):
初始化
def函数名2(self,参数类别):
初始化。。。。实例化变量调用输出classCat:
defeat(self):
print('小猫爱吃鱼')
defdrink(self):
print('小猫要喝水')
tom=Cat()
tom.eat()
tom.drink()例如:计算机中的对象的原型可以将现实生活中的对象经过抽象,映射为程序中的对象。程序中的对象在是通过一种抽象数据类型来描述的,这种抽象数据类型称为类(class)。classCar:#定义一个汽车类例如汽车类:classCar:
color="red"
#汽车有颜色
speed=120
defspeekup(self):#加速方法,
print("红色汽车正在加速...")
defbrake(self):
#刹车方法,
print("红色汽车正在刹车...")开始:class样例类名(object):passclass外部类名(object):class内部类名(object):passclass子类名(父类名):
“”“已显式从另父类继承.""“结束:class样例类名passclass外部类class内部类名pass6、嵌套类的格式7、类的方法的使用
在类的内部,使用def关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数self,且为第一个参数,self代表的是类的实例。类的私有方法__private_method:两个下划线开头,声明该方法为私有方法,只能在类的内部调用,不能在类的外部调用。self.__private_methods。对类名使用大写字母开头的单词,模块名一般用小写加下划线的方式命名。其中:
__init__()方法是对象的“构造函数”,负责在对象初始化时进行一系列的构建操作,包括:对象创建、连接数据库、连接FTP服务器、进行API验证等操作。类的基本使用classA():
def__init__(self):
print(“这里是类的初始化方法”)
defaf(self):
print(“这里是类的普通方法”)
def_ad(self):
self._a1=“这里是安全的”
print(“安全方法:",self._a1)
a=A()
a.af()
a._ad()这里是类的初始化方法这里是类的普通方法安全方法:这里是安全的例1三、类方法及调用方式Python类中常分为实例化方法、静态方法和类方法三种,其中类方法静态方法都可以被类和类实例调用,类实例方法仅可以被类实例调用。类方法的隐含调用参数是类,而类实例方法的隐含调用参数是类的实例,静态方法没有隐含调用参数。1、类实例化方法调用一般通过类名实例化对象方法,再使用对象调用类方法,例如:classPy:
defstudy(self):
print("我们正在学习Python的类调用")
p1=Py()
p1.study()结果:我们正在学习Python的类调用深圳北理莫斯科大学:例2类的实例化方法调用classaddr:def__init__(self,name,url):#建立dd类=name#初始化类变量self.url=urldefuniversity(self):
#建立类方法print()print(self.url)add1=addr('深圳北理莫斯科大学:','')#实例化对象add1.university()#实例调用classPerson:def__init__(self,name):=nameself.sex='男'self.age=18obj=Person('张三')
#自动执行类中的__init__方法print('姓名:',,'性别:',obj.sex,'年龄:',obj.age)结果:姓名:张三
性别:男
年龄:18上述写法也可写成:classPerson:def__init__(self,name,sex,age):=nameself.sex=sexself.age=agedefg1(self):return"姓名:{},性别:{},年龄:{}".format(,self.sex,self.age)p1=Person("张三","男",18)print(p1.g1())结果:姓名:张三,性别:男,年龄:18例3self的使用classPeople(object):def__init__(self,name,age,sex,money):#初始化方法
=nameself.age=age
self.sex=sexself.money=moneydefplay(self):#创建类方法
print(“正在打羽毛球")p1=People('user1',30,'male',10000)#实例对象#输出print("用户名:%s,年龄:%d,性别:%s,工资:%d"%(,p1.age,p1.sex,p1.money))p1.play()用户名:user1,年龄:30,性别:male,工资:10000正在打羽毛球例4刘明,18,男,和家人开车去旅游张帆,22,男,大学毕业准备去工作李思思,10,女,放学回家classPeople(object):#创建一个People类
def__init__(self,name,age,sex):=nameself.age=age
self.sex=sexdefgohome(self):#类中方法1print("{},{},{}放学回家".format(,self.age,self.sex))deftravel(self):#类中方法2print("{},{},{}和家人开车去旅游".format(,self.age,self.sex))defwork(self):#类中方法3print("{}.{},{}大学毕业准备去工作".format(,self.age,self.sex))Liuming=People("刘明",18,"男")#实例对象1zhangfan=People("张帆",22,"男")#实例对象2Lisisi=People(“李思思”,10,“女”)#实例对象3L()#调用zhangfan.work()Lisisi.gohome()例5classDog:def__init__(self,name):=nameself.tricks=[]#为Dog创建一个空列表
defadd_trick(self,trick):self.tricks.append(trick)d=Dog('泰迪')e=Dog('松狮')d.add_trick('在翻跟头')e.add_trick('在玩球')print(,d.tricks)print(,e.tricks)例6泰迪['在翻跟头']松狮['在玩球']使用append添加属性使用类方法编写简单计算器。
classcalculate(object):#定义类
def__init__(self,x,y):#初始化变量
self.x=x
self.y=y
self.result=0#保存结果的变量
defadd(self,x,y):#加法运算方法
self.result=x+y
defsub(self,x,y):#减法运算方法
self.result=x-y
defmul(self,x,y):#乘法运算方法
self.result=x*y
defdiv(self,x,y):#除法运算方法
self.result=x/y
s=calculate(0,0)#类实例化
s.add(3,4)#实例调用
print(s.result)
s.sub(3,4)
print(s.result)
s.mul(3,4)
print(s.result)
s.div(3,4)
print(s.result)运行结果:7-1120.75例7
静态方法是类中的函数,不需要实例,即:静态调用方法不需要实例化就可以由类执行的方法。静态方法是和类本身没有交互,即在静态方法中,不会涉及到类中的方法和属性的操作,可以理解为将静态方法存在此类的名称空间中。因此,使用中若有一个方法实现的功能比较独立就可以使用静态方法实现,在Python引入静态方法的步骤为:(1)通过装饰器@staticmethod定义静态方法。(2)@staticmethod必须写在方法上。(3)调用格式:“类名.静态方法名(参数列表)”,在静态方法中访问实例属性和实例方法会导致错误。2、类的静态方法调用法一:classTest:defcalculate(a,b):result=a*breturnresultTest.calculte=staticmethod(Test.calculate)c=Test.calculate(5,6)print("计算结果:",c)创建静态方法法二:classTest:@staticmethoddefcalculate(a,b):result=a*breturnresultTest.calculte=staticmethod(Test.calculate)c=Test.calculate(5,6)print("计算结果:",c)计算结果:30计算结果:30classPerson():
@staticmethod
defstatic():
print(“这里是类的静态方法”)
definstance(self):
print(“这里是类的实例方法")
Person.static()
#使用类调用
p=Person()
p.instance()
#使用类实例调用例8类的静态方法与实例方法这里是类的静态方法这里是类的实例方法3、类方法调用
类方法是将类本身作为对象进行操作的方法,它和静态方法的区别在于:不管这个方式是从实例调用还是从类调用,它都用第一个参数把类传递过来。类方法需要一个关键词@classmethod装饰,它可以通过实例对象和类对象进行调用,其调用在实例对象初始化之前进行,若需要在初始化前做一些工作时可以考虑使用类方法。classmethod修饰额符对应的函数不需实例化,也不需要self参数,但第一个参数需要是表示自身的cls参数,它可用来调用类的属性,类的方法,实例化对象等。classmethod是用来指定一个类的方法为类方法,没有此参数指定的类的方法为实例方法,使用方法为:classTest:@classmethoddeffunc(cls,arg1,arg2,):classTest:a=100deffunc1(self):print("这里是func1方法内容")@classmethoddeffunc2(cls):print("这里是func2方法内容")print("这里是类变量:",cls.a)cls().func1()Test.func2()例9这里是func2方法内容这里是类变量:100这里是func1方法内容使用类变量。使用@classmethod处理字符串格式classDateTest:def__init__(self,y=0,m=0,d=0):self.y=yself.m=mself.d=d@classmethoddefdealdate(cls,string_date):y,m,d=map(int,string_date.split('-'))date1=cls(y,m,d)returndate1defprint_date(self):print(self.y)print(self.m)print(self.d)d1=DateTest.dealdate("2023-1-31")d1.print_date()例102023131classDateTest:def__init__(self,y=0,m=0,d=0):self.y=yself.m=mself.d=ddefprint_date(self):print(self.y)print(self.m)print(self.d)string_date=("2023-1-31")y,m,d=map(int,string_date.split('-'))d1=DateTest(y,m,d)d1.print_date()2023131不使用@classmethod处理字符串格式例111我在类中2我在类中3类值变化了4类值变化了5类值变化了6又重新赋值啦classTest:#创建类
action='我在类中'#在类中直接赋值print("1",Test.action)#输出类初始值t=Test()#建立类对象调用print("2",t.action)#使用类对象输出类对象值Test.action='类值变化了'#引用类名重新赋值覆盖了原类对象值print("3",Test.action)
#使用类名输出类对象值print("4",t.action)
#使用类对象输出类对象值t.action='又重新赋值啦'#引用类对象重新赋值print("5",Test.action)#使用类名输出类对象值print("6",t.action)
#使用类对象输出类对象值例12类变量的使用四、类调用案例1、类的方法的调用:与普通的函数调用类似(1)类的内部调用:self.<方法名>(参数列表)。(2)在类的外部调用:<实例名>.<方法名>(参数列表)。两种调用方法中,提供的参数列表中都不用包括self调用方法时,把self看成一个参数要传值,传什么对象后面也会对什么对象进行操作,最好传的对象和类的对象一致(传值对象是当前类的实例化),否则会发生不可预期的错误。若存在两个.py文件class1.py和class2.py,他们在同一个文件夹下面,可以通过fromclass1import*或者importclass1来互相调用。使得两个文件中的类相互调用。通过动态实例化class1.py里面的SON类,把class2.py中的ALL类实例通过参数传递给SON,从而调用ALL类的方法。classSON():def__init__(self,instance):self.bat=instancedefgetSon(self):returnself.bat.getAlltest()fromclass1import*classALL():def__init__(self):self.mSon=SON(self)defgetAll(self):print("======输出本类的内容======")returnself.mSon.getSon()defgetAlltest(self):print(“======得到调用类的内容======")Instance=ALL()Instance.getAll()class1.pyclass2.py======输出本类的内容============得到调用类的内容======例13classWasher:def__init__(self):self.water=0self.scour=0defadd_water(self,water):print('需要加水:',water,'公斤')self.water=waterdefadd_scour(self,scour):self.scour=scourprint('需要加洗衣粉:',self.scour,'克')defstart_wash(self):print('开始洗衣服...')if__name__=='__main__':w=Washer()w.add_water(8)w.add_scour(20)w.start_wash()
例14需要加水:8公斤需要加洗衣粉:20克开始洗衣服...编写洗衣程序。运行结果:我是波斯猫我的任务是讨主人喜欢!我的颜色是:黄色,重量是:2.20公斤,有:4只脚,嘴巴会叫我是小黑我的任务是给主人产蛋!我的颜色是:黑色,重量是:1.50公斤,有:2只脚,嘴巴会叫定义一个动物类,添加2个类方法,输出其各自的特征。例如定义一个猫和母鸡方法:例15classAnimal:
#定义类def__init__(self,color,weight,legs,mouth):#初始化类参数self.color=colorself.weight=weightself.legs=legsself.mouth=mouthdefcat(self,name):#类方法1=name#实例变量:定义在方法中的变量,只作用于当前实例的类。print('我是',name)print("我的任务是讨主人喜欢!")defhen(self,name):#类方法2=name#实例变量:定义在方法中的变量,只作用于当前实例的类。print('我是',name)print("我的任务是给主人产蛋!")def__str__(self):#print函数自动调用格式return'我的颜色是:%s,重量是:%.2f公斤,有:%d只脚,嘴巴会%s'%(self.color,self.weight,self.legs,self.mouth)t1=Animal('黄色',2.2,4,'叫')#类的实例化1t1.cat("波斯猫")print(t1)t2=Animal('黑色',1.5,2,'叫')#类的实例化2t2.hen("小黑")print(t2)王方,女,体重55公斤,喜欢跑步,每次跑步减少1公斤,麦片,男,75公斤,喜欢打羽毛球,每周打球减少0.5公斤,编写类方法实现输出。提示:1)建立一个Person类,初始化姓名、性别、体重2)建立一个跑步和一个打球方法3)实例化王方和麦片的数据,调用类输出例16程序代码:classPerson:def__init__(self,name,sex,weight):=nameself.sex=sexself.weight=weightdef__str__(self):return'我的名字叫%s,性别是%s,体重现在是%.1f'%(,self.sex,self.weight)defrun(self):print('%s喜欢跑步'%)self.weight-=2defball(self):print('%s喜欢打羽毛球'%)self.weight-=0.5xx=Person('王方','女',55)xm=Person('麦片','男',75.5)xx.run()xm.ball()print(xx)print(xm)importmath
classtriangle:
def__init__(self,name,a,b,c):
=name#名称
self.__a=a#a,b,c为三角形边长
self.__b=b
self.__c=c
@property
defarea(self):#对外提供的接口,封装了内部实现
s=(self.__a+self.__b+self.__c)/2
returnmath.sqrt(s*(s-self.__a)*(s-self.__b)*(s-self.__c))
S1=triangle("三角形",3,4,5)#加入三角形三条边print(S1.name,S1.area)#通过接口使用area,得到三角形面积结果:三角形6.01、封装使得用户只能借助类方法来访问数据,避免用户对类中属性或方法的不合理操作,且对类进行封装,还可提高代码的复用性。例如:计算三角形面积,对外界来说不需要知道中间的计算过程,把这些对外界无关紧要的内容封装了起来对外界是不见,只需要输入名字比如'三角形',三条边长度,即可得到面积。五、封装、继承与多态
例17封装的使用2、什么是继承Python完全支持继承,重载\派生\多继承有益于增强源代码的复用性。DogCatBridAnimalStudentTeachermanagerPersonObject继承:即一个派生类(derivedclass)继承基类(baseclass)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如:Dog类的对象派生自Animal类,Student类的对象派生自Person类,它们都继承Object类。2、继承的特点(1)在继承中基类的构造(__init__()方法)不会被自动调用,它需要在其派生类的构造中专门调用。(2)在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。在类中调用普通函数时并不需要带上self参数(3)Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。即:先在本类中查找调用的方法,找不到才去基类中找。(4)如果一个类不继承自其它类,就显式的从object继承.嵌套类也一样。class继承类名(基类名):
<语句1>...
<语句-N>3、继承类定义的语法子类名必须定义于包含派生类定义的作用域中。也允许用其他任意表达式代替基类名称所在的位置。当基类定义在另一个模块中时,则:classDerivedClassName(modname.BaseClassName):classFather(object):def__init__(self,profession):
profession='教师'
print(profession)classSon(Father):def__init__(self):
print('儿子职业是:')
super().__init__(self)a=Son()结果:儿子职业是:教师例如:儿子继承父亲的职业
Python中常使用super继承父类的函数,它是一个内置函数,用于调用父类中的方法,语法格式:super(类型[,self])self会首先调用自己的方法或者属性,当自身没有目标属性或方法时,再去父类中寻找;super会直接去父类中寻找目标属性或方法,多用来处理多重继承问题中直接用类名调用父类方法时的查找顺序问题。派生类定义的执行过程与基类相同。当构造类对象时,基类会被记住。此信息将被用来解析属性引用:如果请求的属性在类中找不到,搜索将转往基类中进行查找。如果基类本身也派生自其他某个类,则此规则将被递归地应用。派生类DerivedClassName()会创建该类的一个新实例。派生类可能会重写其基类的方法,所以调用同一基类中定义的另一方法的基类方法最终可能会调用覆盖它的派生类的方法。在派生类中的重载方法实际上可能想要扩展而非简单地替换同名的基类方法。有一种方式可以简单地直接调用基类方法:即调用BaseClassName.methodname(self,arguments)。仅当此基类可在全局作用域中以BaseClassName的名称被访问时方可使用此方式。classPerson(object):def__init__(self,name,sex):=name
self.sex=sexclassStudent(Person):def__init__(self,name,sex,score):super(Student,self).__init__(name,sex)self.score=scoreStudent类需要有name和sex属性,因为Person类中有所以直接继承即可。另外需要新增score属性继承类时一定要使用super(子类名,self).__init__(子类需要继承父类的参数)去初始化父类。否则,继承父类的子类将没有name和sex。super(子类名,self)将返回当前类继承的父类。然后调用__init__方法。此时__init__方法已经不需再传self参数,在super时已经传入。派生类
student()会创建该类的一个新实例。派生类可能会重写其基类Person()的方法,例如:classAnimal(object):defrun(self):print('动物正在跑呢...')classDog(Animal):defrun(self):print('狗正在跑...')defeat(self):print('狗在吃肉...')classCat(Animal):
passdog=Dog()dog.run()dog.eat()cat=Cat()cat.run()狗正在跑...狗在吃肉...动物正在跑呢...继承的使用当子类和父类都存在相同的run()方法时,子类的run()覆盖了父类的run(),在代码运行的时候,总是会调用子类的run()。例18子类类型可以向上转型看做父类类型(子类是父类);父类类型不可以向下转型看做子类类型,因为子类类型多了一些自己的属性和方法。父类与子类类型classPerson(object):def__init__(self,name,sex):=name
self.sex=sexclassStudent(Person):def__init__(self,name,sex,score):super(Student,self).__init__(name,sex)self.score=scoreclassTeacher(Person):def__init__(self,name,sex,course):super(Teacher,self).__init__(name,sex)self.course=course例19父类与子类的使用t=Teacher(‘Jiang’,‘Female’,‘Python语言')s=Student('mary','Female',98)p=Person('Tim','Male')print('姓名:{},性别:{},教授课程:{},正在上课'.format(,t.sex,t.course))print('姓名:{},性别:{},成绩:{},放学回家了'.format(,s.sex,s.score))print('姓名:{},性别:{}'.format(,p.sex))print(isinstance(t,Person))#Trueprint(isinstance(t,Student))#Falseprint(isinstance(t,Teacher))
#Trueprint(isinstance(t,object))
#Trueprint(isinstance(p,Student))#Falseprint(isinstance(p,Teacher))姓名:Jiang,性别:Female,教授课程:Python语言,正在上课姓名:mary,性别:Female,成绩:98,放学回家了姓名:Tim,性别:MaleTrueFalseTrueTrueFalseFalse4、方法重写
如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。如果在子类中定义的一个方法,其名称、返回类型及参数列表正好与父类中某个方法的名称、返回类型及参数列表相匹配,那么可以说,子类的方法重写了父类的方法。方法重写在不同类,是实现多态的必要条件。Python可从一个父类派生出多个子类,可以使子类之间有不同的行为,这种行为称之为多态。即:子类重写父类的方法,使子类具有不同的方法实现。子类与父类拥有同一个方法,子类的方法优先级高于父类,即子类覆盖父类。只要方法存在,参数正确,就可以调用。classA():
def__init__(self):
print('这是A类的初始化属性')
deffun1(self):
print('这是A类的方法')
classB(A):
def__init__(self):
print('这是B类的初始化属性')
super().__init__()#super()函数引入A的初始化属性
deffun2(self):
print('这是B类的方法')
b=B()
b.fun1()#B继承A的fun1方法
b.fun2()
print("B继承A类吗?",issubclass(B,A))
这是B类的初始化属性这是A类的初始化属性这是A类的方法这是B类的方法B继承A类吗?True例20继承与方法的重写例21方法的重写的使用classPerson(object):def__init__(self,name,sex):=nameself.sex=sexdefwhoAmI(self):return'我是中国人,我的名字是%s,是%s生'%(,self.sex)classStudent(Person):def__init__(self,name,sex,score):super(Student,self).__init__(name,sex)self.score=scoredefwhoAmI(self):return'我是一个学生,我的名字是:%s,是%s生,Python成绩是%d'%(,self.sex,self.score)p=Person('张三','男')s=Student('玛利亚','女',88)print(p.whoAmI())print(s.whoAmI())
方法调用将作用在对象的实际类型上。s
是Student类型,它实际上拥有自己的
whoAmI()方法以及从Person继承的whoAmI方法,但调用
s.whoAmI()总是先查找它自身的定义,如果没有定义,则顺着继承链向上查找,直到在某个父类中找到为止。这就称之为多态。我是中国人,我的名字是:张三,是男生我是一个学生,我的名字是:玛利亚,是女生,Python成绩是885、Python多重继承Python支持多继承,一个多继承的定义形如:class子类名(父类名1,父类名2,父类名3):多个父类有同名属性和方法,子类的方法属性__mro__决定了属性和方法的查找顺序。如果多个父类中有同名的属性和方法,则默认使用第一个父类的属性和方法(根据类的魔法属性mro的顺序来查找)。子类重写父类的属性和方法子类和父类的方法名和属性名相同,则默认使用子类的,叫子类重写父类的同名方法和属性。使用重写的目的:当子类发现父类的大部分功能都能满足需求,但是有一些功能不满足,则子类可以重写父类方法。使用super()可以逐一调用所有的父类方法,并且只执行一次。调用顺序遵循mro类属性的顺序。重写之后,如果发现仍然需要父类方法,则可以强制调用父类方法。方法1:指定执行父类的方法无论何时何地,self都表示是子类的对象。在调用父类方法时,通过传递self参数,来控制方法和属性的访问修改。通常用于多继承。
父类名.父类方法(self,参数列表)
父类名().属性/方法
#该方法相当于创建了一个新的父类对象,子类继承了多个父类,若父类修改了,则子类也要多次修改,需要重复多次调用方法2:super(子类名,self).父类方法(参数列表)super(子类名,self).__init__()#执行父类的__init__方法方法3.super().父类方法(参数列表)#执行父类的实例方法super().__init__()
#执行父类的__init__方法当父类方法不能满足子类的需求时,可以对方法进行重写或覆盖父类的方法。classAnimal():defeat(self):print('吃')defdrink(self):print('喝')defrun(self):print('跑')defsleep(self):print('睡')classCat(Animal):defshout(self):print('喵')classHellokitty(Cat):defspeak(self):print('可以说外语')例22覆盖的重写defshout(self):print('喊叫出多种音乐')kt=Hellokitty()kt.shout()喊叫出多种音乐如果子类中,重写了父类的方法,在运行时,只会调用在子类中重写的方法多重继承的目的是从两种继承树中分别选择并继承出子类,以便组合功能使用。如果继承了多个父类,且父类都有同名方法,则默认只执行第一个父类的同名方法只执行一次classA(object):def__init__(self,a):print('这里初始化A类');self.a=aclassB(A):def__init__(self,a):super(B,self).__init__(a);print('这里初始化B类')classC(A):def__init__(self,a):super(C,self).__init__(a);print('这里初始化C类')classD(B,C):def__init__(self,a):super(D,self).__init__(a);print('这里初始化D类')例23多重继承x=A("输出A类的内容");print(x.a)y=B("输出B类的内容");print(y.a)z=C("输出C类的内容");print(z.a)k=D("输出D类的内容");print(k.a)这里初始化A类输出A类的内容这里初始化A类这里初始化B类输出B类的内容这里初始化A类这里初始化C类输出C类的内容这里初始化A类这里初始化C类这里初始化B类这里初始化D类输出D类的内容D同时继承自B和C,B和C又继承自A,因此D拥有了A、B和C的全部功能。如果没有多重继承,就需要在D里写A、B、C的所有功能进去。6、多态多态是一种使用对象的方式,子类重写父类方法,调用不同子类对象的相同父类方法,可以产生不同的执行结果,即:同一个方法,不同对象调用同一方法,实现的功能不一样
好处:调用灵活,有了多态,更容易编写出通用的代码,做出通用的编程,以适应需求的不断变化,增加程序的复用性。例如:Python中的”+”运算方法,
在数字相加时,1+2=3,’a’+‘b’=‘ab’,就是字符串的拼接在列表上:[1]+[2]=[1,2],就是列表拼接;同样的方法名,用在不同对象上,实现的功能完全不一样,这就是多态;多态可以共享某个方法,给所有的类对象使用例24classA():
def__init__(self,name):
self.name=name
defplay(self):
print(self.name,"喜欢打羽毛球")
defwork(self):
print(self.name,"喜欢编程工作")
classB(A):
defplay(self):
print(self.name,"不喜欢打羽毛球,喜欢旅游")
defwork(self):
print(self.name,"讨厌编程工作,喜欢销售")
defstart(ss):
ss.play()
ss.work()
a=A("张三")
b=B("李四")
print(start(a),start(b))张三喜欢打羽毛球张三喜欢编程工作李四不喜欢打羽毛球,喜欢旅游李四讨厌编程工作,喜欢销售NoneNoneclassDog(object):defwork(self):#父类提供统一的方法,哪怕是空方法
passclassArmyDog(Dog):#继承Dogdefwork(self):#子类重写方法,并且处理自己的行为
print('追击敌人')classDrugDog(Dog):defwork(self):print('追查毒品')classPerson(object):defwork_with_dog(self,dog):dog.work()#根据对象不同产生不同的运行效果dog=Dog()#子类对象可以当作父类来使用print(isinstance(dog,Dog))#Truead=ArmyDog()print(isinstance(ad,Dog))#Truedd=DrugDog()print(isinstance(dd,Dog))#Truep=Person()p.work_with_dog(dog)p.work_with_dog(ad)#同一个方法,只要是Dog的子类就可以传递p.work_with_dog(dd)#传递不同对象,最终work_with_dog产生了不同的执行效果例25多态的使用TrueTrueTrue追击敌人追查毒品最终效果Person类中只需要调用Dog对象work()方法,而不关心具体是什么狗。
work()方法是在Dog父类中定义的,子类重写并处理不同方式的实现在程序执行时,传入不同的Dog对象作为实参,就会产生不同的执行效果1.房子有户型,总面积和家具名称列表新房子没有任何的家具2.家具有名字和占地面积,其中床:占4平米衣柜:占2平米餐桌:占1.5平米3.将以上三件家具添加到房子中4.打印房子时,要求输出:户型,总面积,剩余面积,家具名称列表作业1要求:classFurniture():def__init__(self,name,area):=nameself.area=areadef__str__(self):return'[%s]占地:%.2f'%(,self.area)classHouse():def__init__(self,house_type,area):self.house_type=house_typeself.area=areaself.free_area=area#剩余面积
self.item_list=[]def__str__(self):return('户型:%s\n总面积:%.2f[剩余面积:%.2f]\n家具:%s'%(self.house_type,self.area,self.free_area,self.item_list))defadd_item(self,item):ifitem.area>self.free_area:#1.判断家具的面积
print('%s的面积太大,无法添加'%)self.item_list.append()#2.添加家具
self.free_area-=item.area#3.计算剩余面积[床]占地:4.00[衣柜]占地:200.00[写字台]占地:1.50户型:独门独栋总面积:400.00[剩余面积:194.50]家具:['床','衣柜','写字台']bed=Furniture('床',4)print(bed)yigui=Furniture('衣柜',200)print(yigui)table=Furniture('写字台',1.5)print(table)my_house=House('独门独栋',400)my_house.add_item(bed)my_house.add_item(yigui)my_house.add_item(table)print(my_house)作业2要求1.士兵瑞恩有一把AK47
2.士兵可以开火(士兵开火扣动的是扳机)
3.枪能够发射子弹(把子弹发射出去)
4.枪能够装填子弹--增加子弹的数量classGun():def__init__(self,model):self.model=modelself.bullet_count=0defadd_bullet(self,count):self.bullet_count+=countdefshoot(self):ifself.bullet_count<=0:print('%s没有子弹了...'%self.model)self.bullet_count-=1print('%s...%s'%(self.model,self.bullet_count))classSoldier():def__init__(self,name):=nameself.gun=Nonedeffire(self):ifself.gun==None:print('%s还没有枪...'%)self.gun.add_bullet(5)self.gun.shoot()ak47=Gun('ak47')ak47.add_bullet(20)ak47.shoot()ryan=Soldier('Ryan')ryan.gun=ak47ryan.fire()ak47...19ak47...23第6讲文件操作与异常处理深圳北理莫斯科大学:姜增如第6讲主讲内容2异常处理机制3Python的包及使用1文件操作一、Python的文件操作1、打开文件--open函数语法格式:fileobject=open(name[,mode][,buffering])其中:name:变量表示要访问的文件名称字符串值。mode:决定了打开文件的模式:只读,写入,追加等。所有可取值见如下的完全列表。这个参数是非强制的,默认文件访问模式为只读(r)。buffering:若该值为0,则不寄存,值为1,访问文件时会寄存行,若该值为大于1的整数,表明了该值即为寄存区缓冲大小。若取负值,寄存区的缓冲大小则为系统默认。若该文件无法打开,会抛出系统错误信息。若打开的文件写入中文:如若读写文件含有中文:FileObject=open(“文件名","w+",encoding='utf8');注意:使用open()方法一定要保证关闭文件对象,即调用close()方法
Python对文件的基本操作概括为:打开文件、文件操作、关闭文件mode取值不同模式打开文件的完全列表:模式描述t文本模式(默认)。x写模式,新建一个文件,如果该文件已存在则会报错。b二进制模式。+打开一个文件进行更新(可读可写)。U通用换行模式(不推荐)。r以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。rb以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。r+打开一个文件用于读写。文件指针将会放在文件的开头。rb+以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。用于非文本文件如图片等。w打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。wb用于写入二进制格式并打开一个文件,若文件存在则打开从头编辑,原有内容会被删除。若文件不存在,创建新文件。一般用于非文本文件如图片等。w+打开一个文件用于读写。若文件存在则打开文件从开头编辑,原有内容会被删除。若文件不存在,创建新文件。wb+用于读写二进制格式文件。若文件存在则打开从头开始编辑,原有内容会被删除。若文件不存在,创建新文件。一般用于非文本文件如图片等。a用于追加文件。若文件存在,文件指针将放在文件结尾,将新的内容写入到已有内容之后。若文件不存在,创建新文件进行写入。ab用于追加二进制格式文件,若文件存在,文件指针将会放在文件的结尾。新的内容将会追加到已有内容之后。若文件不存在,创建新文件进行写入。a+打开一个文件用于读写,如果该文件已存在,文件指针将会放在文件的结尾。打开时会是追加模式,若文件不存在,创建新文件用于读写。ab+用于追加二进制格式文件,若文件存在,文件指针将会放在文件的结尾。如果文件不存在,创建新文件用于读写。(1)读取文件FileObject.read(size);#读取size指定的字节数FileObject.readline();#读取指针所在行FileObject.readlines();#读取文件列表,每项是以\n结尾的字符串(2)写文件FileObject.write(“字符串”);#把文本或二进制数据写入到文件中FileObject.writelines();#针对列表操作,把字符串列表写入文件中(3)定位操作FileObject.tell()#输出文件当前位置FileObject.seek(os.SEEK_SET)#输出当前指针FileObject.seek(0)#回到文件的开头FileObject.seek(1)#返回文件的当前位置FileObject.seek(2)#到文件的末尾2、文件操作函数如果读写的文件中有中文,必须加入:encoding='utf-8'(1)其他操作:追加、计算等FileObject=open(‘已经存在的文件名','a',encoding='utf8')FileO
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 消保考试题库及答案
- 业务学习考核试题及答案
- 2026年西藏(公务员)行测真题(含答案)
- 2025年广西壮族自治区防城港市七年级历史上册期中考试试卷及答案
- 医学课件-全自动除颤仪的操作流程
- 2026年中国不锈钢缠绕垫片市场调查研究报告
- 2026年中国三相复费率/预付费电能表市场调查研究报告
- 2026年中国丁维钙粉市场调查研究报告
- 2026年中国95%醚菊酯原药市场调查研究报告
- 2026年轻纺行业技能鉴定考试-纺织机器设备安装工历年参考题库含答案解析
- 2026年苏科版八年级信息技术上册(全册)教学设计(附目录)
- 浙江杭州育才中学2026-2027学年七年级上学期开学检测数学试题(含简单答案)
- 业主委员会考核物业评分细则
- 2026年重庆市“五方面人员”选拔乡镇领导班子考试历年参考题库(含完整答案)
- 人工拆除工程施工方案方案
- 隧道掌子面素描图文讲解
- 2026新版海姆立克急救法培训
- 2026修订二手车背户买卖协议
- 统编版八年级道德与法治上册知识点清单总结复习清单
- 2025年10月25日全国事业单位联考C类《职业能力倾向测验》真题及答案【含解析】
- 江苏疾控中心招聘笔试题库
评论
0/150
提交评论