四. python面向对象(继承)
一. 继承
class A:pass # 父类 基类 超类 class B:pass # 父类 基类 超类 class A_son(A,B): pass # 子类 派生类 class AB_son(A):pass # 子类 派生类 # 一个类 可以被多个类继承 # 一个类可以继承多个父类 print(A_son.__bases__) # 查看类的继承__bases__ (<class '__main__.A'>, <class '__main__.B'>) print(AB_son.__bases__) # 查看类的继承__bases__ (<class '__main__.A'>,) print(A.__bases__) # 查看类的继承__bases__ 在python 中没有父类 都是 object儿子 (<class 'object'>,)
class Per(object): def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex class Dog(Per): pass aa=Dog("张三",25,"男") print(aa.age) # 25 print(aa.name) # 张三
class Aa(object): def __init__(self, name,aggr,hp): self.name = name self.aggr= aggr self.hp=hp def eat(self): print("吃了啊哈哈哈1111111111111111111111111111111111哈") class Do(Aa): def __init__(self, name, aggr,hp,kind): Aa.__init__(self,name,aggr,hp) self.kind=kind def eat(self): Aa.eat(self) # 去继承父类的吃的方法 意思是既想实现新的功能 也想使用父类原有的功能 还需要在子类中再调用 print("222222222222222222222222222222222222222lalalalallaal") aa=Do("张三",100,22,5) print(aa.name) # 张三 print(aa.kind) # 5 print(aa.aggr) # 100 print(aa.hp) # 22 aa.eat() #父类方法 和子类方相同 同时调用了 # 吃了啊哈哈哈1111111111111111111111111111111111哈 # 222222222222222222222222222222222222222lalalalallaal
class Aa(object): def __init__(self, name,aggr,hp): self.name = name self.aggr= aggr self.hp=hp def eat(self): print("吃了啊哈哈哈哈") class Do(Aa): def __init__(self, name, aggr,hp,kind,lover): super().__init__(name, aggr,hp) self.kind=kind # 自己的属性叫派生属性 self.lover=lover def eat(self): print("2222222222222222222222222") aa=Do("张三",100,22,5,66666666666666) aa.eat() # 这个是调用自己的方法 print(aa.lover) # 66666666666666 super(Do,aa).eat() # super 是可以掉用父类的方法 格式 是 super(被继承的类,实例化)
# 这是爸爸类 class Baba(object): money = 100 def __init__(self, name): print("爸爸") self.name = name def da_ren(self): print("%s正在打儿子" % self.name) # 儿子类 class Son(Baba): pass print(Son.money) # 100 print(Baba.__dict__) print(Son.__dict__) # {'__module__': '__main__', 'money': 100, '__init__': <function Baba.__init__ at 0x0000019F1E28B9D8>, 'da_ren': <function Baba.da_ren at 0x0000019F1E28BA60>, '__dict__': <attribute '__dict__' of 'Baba' objects>, '__weakref__': <attribute '__weakref__' of 'Baba' objects>, '__doc__': None} # {'__module__': '__main__
# 这是爸爸类 class Baba(object): money=100 def __init__(self,name): self.name=name def da_ren(self): print("%s正在打儿子"%self.name) # 儿子类 class Son(Baba): pass a1=Son("张三") print(a1.name) print(a1.money) # 爸爸 # 张三 # 100
class Person(object): def __init__(self, name, gender): self.name = name self.gender = gender def run(self,aa): print("我喜欢%s是一个"%aa,self.gender) class Teacher(Person): def __init__(self, name, gender, course,age): super(Teacher, self).__init__(name, gender) self.course = course self.age=age def suger(self,cc): print("我是"+self.name+"喜欢"+self.course+"年龄%s"%cc) def run(self): print("我是子类哈哈哈哈") t = Teacher('张三', '男', 'English',"22") print(t.name) # 张三 print(t.course) # English print(t.age) # 22 t.run() # 如果子类和父类定义的方法名相同时 默认时先调用子类 t.suger("222222") # 使用super去调用父类方法 aa=super(Teacher,t) aa.run("3333333333333") # 张三 # English # 22 # 我是子类哈哈哈哈 # 我是张三喜欢English年龄222222 # 我喜欢3333333333333是一个 男
继承一个类: 如果已经定义了Person类,需要定义新的Student和Teacher类时,可以直接从Person类继承: class Person(object): def __init__(self, name, gender): self.name = name self.gender = gender 定义Student类时,只需要把额外的属性加上,例如score: class Student(Person): def __init__(self, name, gender, score): super(Student, self).__init__(name, gender) self.score = score 一定要用 super(Student, self).__init__(name, gender) 去初始化父类,否则,继承自 Person 的 Student 将没有 name 和 gender。 函数super(Student, self)将返回当前类继承的父类,即 Person ,然后调用__init__()方法,注意self参数已在super()中传入,在__init__()中将隐式传递,不需要写出(也不能写)。
class Person(object): def __init__(self, name, gender): self.name = name self.gender = gender def run(self,aa): print("我喜欢%s是一个"%aa,self.gender) class Teacher(Person): def __init__(self, name, gender, course,age): Person.__init__(self,name, gender) self.course = course self.age=age def suger(self,cc): print("我是"+self.name+"喜欢"+self.course+"年龄%s"%cc) def run(self): print("我是子类哈哈哈哈") t = Teacher('张三', '男', 'English',"22") print(t.name) # 张三 print(t.course) # English print(t.age) # 22 t.run() # 如果子类和父类定义的方法名相同时 默认时先调用子类 t.suger("222222") # 使用super去调用父类方法 aa=super(Teacher,t) aa.run("3333333333333") # 张三 # English # 22 # 我是子类哈哈哈哈 # 我是张三喜欢English年龄222222 # 我喜欢3333333333333是一个 男
# 温度temperature # 多态:就是运行时 绑定的状态 class H2o(object): def __init__(self,name,temperature): self.name=name self.temperature=temperature def turn_ice(self): if self.temperature<0: print("[%s]温度太低结冰了"%self.name) elif self.temperature>0 and self.temperature<100: print("[%s]液化成水"%self.name) elif self.temperature>100: print("[%s]温度太高成水蒸气"%self.name) # 水 class Water(H2o): pass # 固态 class Ice(H2o): pass # 气态 class Steam(H2o): pass a1=Water("水",60) a2=Ice("冰",-100) a3=Ice("蒸汽",1000000) # 就是不同的对象调用相同的方法 def func(obj): obj.turn_ice() func(a1) # [水]液化成水 func(a2) # [冰]温度太低结冰了 func(a3) # [蒸汽]温度太高成水蒸气
# 定义交通工具 地铁 # 速度 speed # 乘坐 lood # 能源 power # # 那条线路 line # 定义交通工具 class Vehicle: Country="china" def __init__(self, name,speed,load,power): self.name=name self.speed=speed self.load=load self.power=power def run(self): print("地铁开动了1111111111111111111111111111111") # 地铁 class Subway(Vehicle): def __init__(self,name,speed,load,power,line): Vehicle.__init__(self,name,speed,load,power) # 调用父类的方法实例 self.line=line def show_info(self): print(self.name,self.line,self.speed,self.load,self.power) def run(self): print("%s %s开的了"%(self.name,self.line)) a=Vehicle("成都地铁","10m/s","500人","电") a.run() # 地铁开动了1111111111111111111111111111111 a=Subway("成都地铁","10m/s","500人","电","6号线") a.show_info() # 成都地铁 6号线 10m/s 500人 电 a.run()# 成都地铁 6号线开的了 print(a.Country)# china
# 定义交通工具 地铁 # 速度 speed # 乘坐 lood # 能源 power # # 那条线路 line # 定义交通工具 class Vehicle: Country="china" def __init__(self, name,speed,load,power): self.name=name self.speed=speed self.load=load self.power=power def run(self): print("地铁开动了1111111111111111111111111111111") # 地铁 class Subway(Vehicle): def __init__(self,name,speed,load,power,line): Vehicle.__init__(self,name,speed,load,power) # 调用父类的方法实例 self.line=line def show_info(self): print(self.name,self.line,self.speed,self.load,self.power) def run(self): Vehicle.run(self) # 调用父类的方法 print("%s %s开的了"%(self.name,self.line)) a=Subway("成都地铁","10m/s","500人","电","6号线") a.show_info() # 成都地铁 6号线 10m/s 500人 电 a.run()# 成都地铁 6号线开的了 print(a.Country)# china """Vehicle.__init__(self,name,speed,load,power) 相当于调用父类的 def __init__(self, name,speed,load,power): self.name=name self.speed=speed self.load=load self.power=power"""
1. 多继承
类名.__mro__方法 查看广度优先的继承顺序
# 多继承:
# 按照名字顺序 继承
# 新式类 :广度优先 类名.mro方法 查看广度优先的继承顺序
# 经典类 : 深度优先
class A:
def func(self):
print("A")
class B:
def func(self):
print("B")
class C:
def func(self):
print("C")
class D(A,B,C):
def func(self):
print("D")
f=D()
f.func()
print(D.__mro__)
# <built-in method mro of type object at 0x000001A075553568>
# (<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class 'object'>)
class A: def func(self): print("A") class B: def func(self): print("B") class C: def func(self): print("C") class D(A,B,C): def func(self): print("D") f=D() f.func() super(D,f).func()
使用import 来继承(分文件来继承 注意在同一个文件夹下面)
# per.py 文件 class Per(object): def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def eat(self): print("我是吃吃—————我是人类吃———————————>") def su(self): print("我性别是男-----",self.sex)
# gril.py 文件 from per import Per class Gr(Per): def __init__(self,name,age,sex,money,like): super().__init__(name,age,sex) self.money=money self.like=like def eat(self): # Per.eat(self) print("我是女子吃吃吃-=========1111111111111111====>") def o(self): print("这是钱",self.money)
# son.py 文件
from per import Per class So(Per): def __init__(self,name,age,sex,xi,wa,lan): super().__init__(name,age,sex) self.xi=xi self.wa=wa self.lan=lan def p(self): print("我是帅哥了哈哈哈") def f(self,cc): print(self.lan,"---------------比较花钱",cc)
# mian.py 执行文件 from gril import Gr from son import So if __name__=="__main__": aa=Gr("张三",25,"女","20000元","漂亮") aa.su() # 我性别是男----- 女 aa.eat() # 我是女子吃吃吃-=========1111111111111111====> aa.o() # 这是钱 20000元 super(Gr,aa).eat() # 我是吃吃—————我是人类吃———————————> print("***********************************11111111111111111111*******************************************") bb=So("李四",6666,"男","哈哈","222","nice to") bb.su() # 我性别是男----- 男 bb.eat()# 我是吃吃—————我是人类吃———————————> bb.p()# 我是帅哥了哈哈哈 bb.f("去你妈的哈哈哈哈")# nice to ---------------比较花钱 去你妈的哈哈哈哈
例子 爸爸和妈妈方法 都让儿子继承
# Father.py class Father(object): def __init__(self,money): self.money=money def play(self): print("这是paly哈哈哈哈哈哈哈哈") def func(self): print("这是func111111111111111111啦啦啦啦啦啦啦啦")
# Mother.py 文件 class Mother(object): """docstring for Father""" def __init__(self,faceValue): self.faceValue=faceValue def eat(self): print("我要吃哈哈哈哈eat") def func(self): print("这事了绿绿绿绿func")
Child.py 文件 # 多继承 这个Child 即继承了父类 和母类 from Father import Father from Mother import Mother class Child(Father,Mother): def __init__(self,money,faceValue): Father.__init__(self,money) Mother.__init__(self,faceValue)
# mian.py 执行文件 from Child import Child def main (): c=Child(300,100) print(c.money,c.faceValue) c.piay() c.eat() # 注意:父类中方法名相同 默认调用的是在括号中排前面的父类中方法 c.func() if __name__=="__main__": main()
# a.py 文件 class Aa (object): name="张三" age=0 def __init__(self,lover,la): self.lover=lover self.la=la def aa(self): print("11") print(self.la) def bb(self): print("22") print(self.lover)
# b.py文件 class Ba(object): def cc(self): print("33") def dd(self): print("44")
mian.py 执行文件 from a import Aa from b import Ba # 方法一 class Cc(Aa,Ba): def __init__(self,lover,la,idi): super(Cc,self).__init__(lover,la) self.idi = idi def gg(self): print(self.idi) f=Cc("66666","888888",7) f.aa() f.bb() f.gg() # 方法二 class Cc(Aa,Ba): def __init__(self,lover,la,hh): self.__hh=hh Aa.__init__(self,lover,la) Ba.__init__(self) def jj(self): print(self.__hh) f=Cc("66666","888888",99999) f.aa() f.bb() f.jj() print(Cc.name)