继承
资源的继承:
当子类继承父类的属性时,如果对子类的该属性重新赋值,那么该如何通过子类再去寻找父类呢?
3种形态:
单继承链 :深度优先
无重叠的多继承 :深度优先
有重叠的多继承:老版本深度优先会用不了,产生重复时优先后出的,新版本用的不是广度优先
资源的使用:
python2.3-2.7 经典类、新式类用的是C3算法
python3.X之后 都是新式类 用的C3算法
用python中的inspect模块getmro可以查看调用顺序
资源的覆盖:
在MRO资源检索链中,优先选择优先级比较高的资源而摒弃优先级比较低的资源,造成“覆盖”的假象。
资源的累加:子类相比于父类,多一些自己特有的资源
class D(object):
def __init__(self):
print("d")
class B(D):
def __init__(self):
D.__init__(self)
print("b")
class C(D):
def __init__(self):
D.__init__(self)
print("c")
class A(B,C):
def __init__(self):
B.__init__(self)
C.__init__(self)
print("a")
B()
#output:
#>>d
#>>b
A() #结果显示重复调用了d
#output:
#>>d
#>>b
#>>d
#>>c
#>>a
当使用菱形继承时,会出现重复调用的现象,为了避免出现,使用super函数
super(参数1,参数2)
沿着参数2的MRO链条,找到参数1的下一个节点,所以参数2必须是子类或者本身才能包含要找的类。
更通俗的解释就是,在参数2开始的链条范围内找到参数1的下一个节点。所以参数2范围要更广。
class D(object):
def __init__(self):
print("d")
class B(D):
def __init__(self):
super().__init__()
print("b")
class C(D):
def __init__(self):
super().__init__()
print("c")
class A(B,C):
def __init__(self):
# B.__init__(self)
# C.__init__(self)
super().__init__()
print("a")
A()
#output:
#>>d
#>>c
#>>b
#>>a
通过类名来获取init:
class D(object):
def __init__(self):
print("d")
class B(D):
def __init__(self):
super(B,self).__init__()
#通过self的类来间接获得类的名字,即便后期更改类名也不影响调动
print("b")
class C(D):
def __init__(self):
super(C,self).__init__()
print("c")
class A(B,C):
def __init__(self):
B.__init__(self) #找到B的init然后把A实例传递进去
C.__init__(self)
print("a")
A()
# output:
#>>d
#>>c
#>>b
#>>d
#>>c
#>>a
多态
一个类所延伸的多种形态,调用时的多种形态;
在其他语言中,需要提前设定好参数的类型;但在python中完全不需要,因为在继承的前提下,使用不同的子类,调用父类的同一个方法,产生不同的功能。只需要关注有没有你需要的方法或者属性。
抽象类与抽象方法:需要先导入abc模块
抽象类:可以通过实例对象调用抽象类,不过没有实际意义。比如调用Animal下的“叫声”。通过abc模块完善
实例开发:
class Dog:
def __init__(self,name,age=1):
self.name=name
self.age=age
def eat(self):
print("名字叫{}的{}岁小狗在吃饭".format(self.name,self.age))
def play(self):
print("名字叫{}的{}岁小狗在玩耍".format(self.name, self.age))
def sleep(self):
print("名字叫{}的{}岁小狗在睡觉".format(self.name, self.age))
d=Dog("小黑")
d.eat()
#output:名字叫小黑的1岁小狗在吃饭
class Dog:
def __init__(self,name,age=1):
self.name=name
self.age=age
def eat(self):
print("%s在吃"%self)
def play(self):
print("%s在玩耍"%self)
def sleep(self):
print("%s在睡觉"%self)
def __str__(self):
return ("名字叫{}的{}岁小狗".format(self.name, self.age))
d=Dog("小黑")
d.play()
#output:名字叫小黑的1岁小狗在玩耍
class Person:
def __init__(self,name,pets,age=1):
self.name=name
self.age=age
self.pets=pets
def eat(self):
print("%s在吃"%self)
def play(self):
print("%s在玩耍"%self)
def sleep(self):
print("%s在睡觉"%self)
def yangchongwu(self):
for pet in self.pets:
pet.eat()
pet.play()
pet.sleep()
def petswork(self):
for pet in self.pets:
pet.work()
def __str__(self):
return ("名字叫{}的{}岁小狗".format(self.name, self.age))
class Dog:
def __init__(self,name,age=1):
self.name=name
self.age=age
def eat(self):
print("%s在吃"%self)
def play(self):
print("%s在玩耍"%self)
def sleep(self):
print("%s在睡觉"%self)
def work(self):
print("%s在看家"%self)
def __str__(self):
return ("名字叫{}的{}岁小狗".format(self.name, self.age))
class Cat:
def __init__(self,name,age=1):
self.name=name
self.age=age
def eat(self):
print("%s在吃"%self)
def play(self):
print("%s在玩耍"%self)
def sleep(self):
print("%s在睡觉"%self)
def work(self):
print("%s在捉老鼠"%self)
def __str__(self):
return ("名字叫{}的{}岁小猫咪".format(self.name, self.age))
#output:>>
# 名字叫小黑的18岁小狗在吃
# 名字叫小黑的18岁小狗在玩耍
# 名字叫小黑的18岁小狗在睡觉
# 名字叫小红的2岁小猫咪在吃
# 名字叫小红的2岁小猫咪在玩耍
# 名字叫小红的2岁小猫咪在睡觉
# 名字叫小黑的18岁小狗在看家
# 名字叫小红的2岁小猫咪在捉老鼠
上述代码对每一个类单独实现,但是每个类中很大一部分有相同属性和相同方法。要实现简化。
class Animal:
def __init__(self,name,age=1):
self.name=name
self.age=age
def eat(self):
print("%s在吃饭"%self)
def play(self):
print("%s在玩耍"%self)
def sleep(self):
print("%s在睡觉"%self)
class Person(Animal):
def __init__(self,name,age,pets): #后续只要传pet就行
super(Person,self).__init__(name,age) #想在子类里面使用父类的资源
self.pets = pets
def yang_pets(self):
for pet in self.pets: #类似于多态
pet.eat()
pet.play()
pet.sleep()
def pets_work(self): #类似于多态
for pet in self.pets:
pet.work()
def __str__(self):
return ("名字叫{}的{}岁的主人".format(self.name, self.age))
class Dog(Animal):
def work(self):
print("%s在看家"%self)
def __str__(self):
return ("名字叫{}的{}岁小狗".format(self.name, self.age))
class Cat(Animal):
def work(self):
print("%s在捉老鼠"%self)
def __str__(self):
return ("名字叫{}的{}岁小猫咪".format(self.name, self.age))
d=Dog("小黑",8)
c=Cat("小红",2)
p=Person('主人',18,[d,c])
p.yang_pets()
p.pets_work()
c.eat()
实例2: