python的面向对象,类,以及类的使用
对象(object),python中,一切皆对象。
对象分为两个部分:静态对象,动态对象
类:
表示具有相同属性的方法和对象的集合。封装对象的属性和行为的载体,具有相同属性和行为的称为一类
面向对象程序设计的三大基本特点:封装,继承,多态。
封装:保证类内部结构完整性,,使用类的用户只能执行公开的数据,提高程序的可维护性。
继承:实现重复利用,子类通过继承父类的的属性和行为同时又添加了自己的特有的属性和行为
多态:一个类衍生出不同的子类,子类继承父类的特征的同时,也具备自己的特征,并且可以实现不同的功能。
在使用类时,需要先定义类,在创建类的实例,通过类的实例可以访问类的属性方法。
1、归类——我们可以把学生都归成一个学生类。
2、抽象出特征——学生有什么特点?(学校、姓名、性别、年龄)
3、抽象出技能——学生有什么技能?(学习、吃饭、打球、睡觉)
定义类:
class ClassName(object):#一般定义类每个单词开头大写,‘驼峰式命名法’,惯例。
创建类的实例:
class Students(object): #类 school = '宏福教育' #属性 classes = '1807班' #属性 gender = 'man' #属性 stu1 = Students() #声明实例,继承Students的属性 # stu2 = Students() #声明实例,继承Students的属性 print(stu1.school) #查看stui的school属性 print(stu1.classes) #查看classes属性 print(stu1.gender) #查看gender属性
宏福教育
1807班
man
可在类中添加函数属性
class Students(object): #类 classes = '1807班' #属性 gender = 'man' #属性 def school(self,name): #可以写形参,但是self形参必须有,而且在第一位 print('%s是宏福学校' % name) stu1 = Students() #声明实例,继承Students的属性 stu1.school('zl') #查看实例stu1的school函数属性,可传参数
zl是宏福学校
__init__(self)
初始化方法;每当创建一个类的实例时,python都会自动执行它,必须包含一个self参数,并且必须是第一个参数。在实例的方法调用时会自动传递实际参数self为实例名
class Students(object): #类 school = '宏福学校' def __init__(self,name,age): #设置初始化函数,self=实例名, self.qwe = name #将name形参赋值给self.name self.asd = age #将age形参赋值给self.age def event(self): print('%s is study,age is %s' % (self.qwe,self.asd)) #调用self.name和self.age的值 stu1 = Students('lucy',18) #创建实例 stu1.event() #查看实例属性 stu2 = Students('harry',29) #创建实例 stu2.event() #查看实例属性 stu3 = Students('tom',20) #创建实例 stu3.event() #查看实例属性
只要声明实例就会自动执行init下的代码
lucy is study,age is 18 harry is study,age is 29 tom is study,age is 20
__str__(self)
初始化返回值,无需调用就会将str里面的函数自动执行,然后return返回
class Person: def __init__(self, name, weight): self.name = name self.weight = weight def __str__(self): return '名字:%s\n体重:%s\n' % (self.name, self.weight) xm = Person('小明', 75) print(xm)
结果无需调用函数,直接print就能将return后面的值返回,每次声明一个实例都会自动执行。
名字:小明
体重:75
对属性的增删改查
#对上面的代码进行操作 stu1 = Students('lucy',18) #创建实例 print(stu1.school) #查看 stu1.school = '宏福' #修改 print(stu1.school) #打印修改后的 stu1.city = '北京' #添加属性 print(stu1.city) #打印添加的属性 del stu1.city #删除city属性
封装
我们家里都有电视机,从开机,浏览节目,换台到关机,我们不需要知道电视机里面的具体细节,只需要在用的时候按下遥控器就可以完成操作,这就是功能的封装。
在用支付宝进行付款的时候,只需要在用的时候把二唯码给收款方或是扫一下收款方提供的二唯码就可以完成支付,不需要知道支付宝的支付接口,以及后台的处理数据的能力,这就是方法的封装。
案例:
需求:
1:小明体重75公斤
2:小明每次跑步都会减肥0.5公斤
3:小明每次吃东西都会增加1公斤
class Person: def __init__(self, name, weight): self.name = name self.weight = weight def run(self): #定义run技能 self.weight -= 0.5 #体重减0.5 def eat(self): #定义eat技能 self.weight += 1 #体重增加1 def __str__(self): #定义返回值 return '名字:%s\n体重:%s\n' % (self.name, self.weight) xm = Person('小明', 75) #声明实例 xm.eat() #调用eat技能 xm.run() #调用run技能 print(xm)
名字:小明
体重:75.5
案例:
需求:
房子包含:户型,家具列表,
家具包含:床(6平米),电视(2平米),餐桌(3平米)
把家具添加到房子中
查看房子的:户型,总面积,剩余面积,家具列表。
#本着定义类要从小到大的原则,所以要先定义家具类,在定义房子类 class Furniture(object): #定义家具类 def __init__(self,name,area): #初始化 self.name = name #家具名 self.area = area #家具面积 print( '现在商场有一个家具%s,占地%s平米\n' % (self.name,self.area)) class House(object): #定义房子函数 def __init__(self,type,sum): #初始化 self.type = type #房子类型 self.sum = sum #房子总面积 self.free = sum #房子剩余面积 self.items = [] #房子里的家具列表 def add_furniture(self,item): #定义技能 self.free = self.free - item.area #计算剩余面积 self.items.append(item.name) #将家具添加到家具列表 def __str__(self): #设置返回值 return '户型为:%s\n总面积:%s平米\n剩余面积是%s平米\n家中有家具%s' % (self.type,self.sum,self.free,self.items) bed = Furniture('席梦思',6) #在家具创建床的实例对象 tv = Furniture('电视',2) #在家具创建电视的实例对象 table = Furniture('餐桌',5) #在家具创建餐桌的实例对象 house = House('一室一厅',20) #创建实例,传户型和总面积实参 house.add_furniture(bed) #给house添加bed house.add_furniture(table) #给house添加table house.add_furniture(tv) #给house添加tv print(house) #打印返回值
现在商场有一个家具席梦思,占地6平米 现在商场有一个家具电视,占地2平米 现在商场有一个家具餐桌,占地5平米 户型为:一室一厅 总面积:20平米 剩余面积是7平米 家中有家具['席梦思', '餐桌', '电视']
案例:
需求:
士兵:叫许三多,有一把枪,有一把AK47,可以装填子弹。
枪:叫AK47,能够发射子弹。
import time class Gun(object): #创建枪类 def __init__(self,gun_type): self.gun_type = gun_type #初始化枪的型号 self.bullet = 0 #初始化子弹的数量 def add_count(self, count): #添加子弹 self.bullet += count def shoot(self): #射击 if self.bullet > 0: #假如子弹数量大于0 for i in range(self.bullet): self.bullet -= 1 print('冲啊.......突突突突.......[%s]' % self.bullet) time.sleep(0.5) else: print('没有子弹啊,兄弟,别这么坑我啊???')#否则没有就显示没有子弹 class Soldier: #创建一个士兵的类 def __init__(self, name,gun=None): self.name = name #初始化士兵的姓名 self.gun = gun #初始化枪 def fire(self): #开火方法 if self.gun: #假如有枪 self.gun.shoot() #那就射击 else: #不然就显示没有枪 print('没有枪啊,兄弟,你让我去送死吗??') ak47 = Gun('AK47') #创建一个枪的对象叫ak47 ak47.add_count(10) #添加10颗子弹 xsd = Soldier('许三多') #实例化一个许三多的士兵对象 xsd.gun = ak47 #把枪交到许三多手中 xsd.fire() #开火
冲啊.......突突突突.......[9] 冲啊.......突突突突.......[8] 冲啊.......突突突突.......[7] 冲啊.......突突突突.......[6] 冲啊.......突突突突.......[5] 冲啊.......突突突突.......[4] 冲啊.......突突突突.......[3] 冲啊.......突突突突.......[2] 冲啊.......突突突突.......[1] 冲啊.......突突突突.......[0]
继承
可以继承一个,也可以继承多个,实现可代码的重复利用性,相同的代码不需要重复写。
重写
当父类的方法不能够满足,不适合子类的需时,可以将父类的方法在子类中重写
扩展
当父类的方法不能够完全满足于子类时,可以对父类的方法进行扩展
class Anamal(object): #动物类 def eat(self): #定义eat的技能 print('吃') def drink(self): #定义drink的技能 print('喝') class Dog(Anamal): #狗类,继承动物类的所有属性(继承) def bark(self): #添加自己特有的属性 print('汪汪叫') class XiaoTianQuan(Dog): #哮天犬继承狗类的属性 def fly(self): #添加自己的属性 print('我会飞啦!!!!') def bark(self): #对父类方法的重写(修改) print('牛逼的叫.......') class Shengquan(Dog): #添加神犬的类(继承dog) def bark(self): #扩展父类的方法 print('霸道的叫') #扩展霸道的叫 super().bark() #依旧保留父类原有的技能 dog = XiaoTianQuan() #声明哮天犬实例 dog.eat() #调用吃的技能 1 dog.drink() #调用喝的技能 2 dog.bark() #调用重写后的叫的技能 3 dog.fly() #调用添加的fly技能 4 sq = shengquan() #声明神犬实例 sq.bark() #调用扩展后的技能 5
吃 #1 喝 #2 牛逼的叫....... #3 我会飞啦!!!! #4 霸道的叫 #5 汪汪叫 #5
多态
子类继承父类特征的同时还拥有自己特征,并且能够实现不同的效果,
类方法:
@classmethod类方法
一般来说,如果要使用一个类的方法,需要先实例化一个对象在调用。
而@classmethod装饰类方法就不需要实例化,直接类名.方法(),就可以调用,当然,也可以用实例化调用。
class Anamal(object): # 动物类 @classmethod def eat(self): #定义eat的技能, print('吃') def drink(self): #定义drink的技能 print('喝') Anamal.eat() #可以通过类名调用 dog = Anamal() #必须实例化才可以调用 dog.drink()
吃 #通过类名直接调用 喝 #通过实例化后调用
@staticmethod静态方法
装饰静态方法,也可以不用实例化就可以调用,也可以实例化后调用。
class C(object): @staticmethod def f(): #函数()不需要传参 print('aaa') C.f() # 静态方法无需实例化 cobj = C() cobj.f() #也可以实例化后调用
@staticmethod和@classmethod的区别
@classmethod:需要传self参数
@staticmethod:不用传参,静态