继承 正常代码中 单继承 == 减少了代码的重复 继承表达的是一种 子类是父类的关系 使用组合和继承的关键点、需要看是==是的关系 = 还是有的关系 1、老师有生日[组合]、不能说老师是生日 、教授是老师[继承] 2、查看是否有相同代码、相同代码即用继承 单继承 几个类之间的相同代码抽象出来,成为父类 子类自己没有的名字,就可以使用父类的方法和属性 如果子类自己有,先使用自己的 在类中使用self的时候,一定要看清楚self指向谁 一个类可以被多个类继承 一个类可以继承多个父类 #python里独有
# -*- coding:utf-8 -*-
class a(object):pass #父类,基类,超类
class b:pass
class a_son(a,b):pass #子类,派生类
class b_son(b):pass
#一个类可以被多个类继承
#一个类可以继承多个父类 #python里独有
print(a_son.__bases__) #查看继承了那些父类
print(b_son.__bases__) #查看继承了那些父类
print(a.__bases__)
#-------------------------------------------------------
D:\python\python.exe F:/运维笔记/python/面向对象/016面向对象继承.py
(<class '__main__.a'>, <class '__main__.b'>)
(<class '__main__.b'>,)
(<class 'object'>,)
对于之前的案例进行修改和进阶(创建角色、怪物、相互攻击) 节省代码量、重复的属性可以放到父类、
# -*- coding:utf-8 -*-
class Animal:
def __init__(self,name,hp,aggr):
self.name = name
self.hp = hp
self.aggr = aggr
class Dog(Animal):
def bite(self,person):
person.hp -= self.aggr
print('%s攻击了%s,%s掉了%s的血' %(self.name,person.name,person.name, self.aggr))
class Person(Animal):
def attack(self,dog):
dog.hp -= self.aggr
print('%s攻击了%s,%s掉了%s的血' %(self.name,dog.name,dog.name, self.aggr))
gouzi = Dog('树精',1000,200,)
nezha = Person('哪吒',1000,300,)
print(gouzi.__dict__)
print(nezha.__dict__)
#D:\python\python.exe F:/运维笔记/python/面向对象/017面向对象继承02.py
{'name': '树精', 'hp': 1000, 'aggr': 200}
{'name': '哪吒', 'hp': 1000, 'aggr': 300}
父类中没有的属性、在子类中出现,叫做派生属性
父类中没有的方法、在子类中出现,叫做派生方法
只要是子类的对象调用方法,子类和父类中都有的话,一定用子类的,子类中没有才找父类,如果父类也没有则报错
如果还想用父类的、则需要单独调用,需要传self参数
Animal.__init__(self,name,hp,aggr) 方法一调用父类
super().__init__ 方法二调用父类
super() 不仅可以再类的内部使用,也可以再类的外部使用
super()内部使用: super().__init__(name,hp,aggr) #不需要传类名
super()外部使用:super(Dog,gouzi).eat() #需要传类名字和对象名
#方法一调用父类 Animal.__init__(self,name,hp,aggr)
class Animal:
def __init__(self,name,hp,aggr):
self.name = name
self.hp = hp
self.aggr = aggr
def eat(self):
self.hp += 100
print('%s 使用了金疮药,血量增加到 %s' % (self.name, self.hp))
class Dog(Animal):
def __init__(self,name,hp,aggr,kind):
Animal.__init__(self,name,hp,aggr) #Animal.__init__(self,name,hp,aggr) #方法一调用父类
self.kind = kind #派生属性
def eat(self):
Animal.eat(self) #如果既想使用父类原本的功能,也想实现新的功能,则需要在子类中调用父类
self.teeth = 2
print('%s 使用了金疮药,增加两颗牙齿' % (self.name))
def bite(self,person):
person.hp -= self.aggr
class Person(Animal):
def __init__(self,name,hp,aggr,sex,money):
Animal.__init__(self, name, hp, aggr)
self.sex = sex #派生属性
self.money = 0 #派生属性
def eat(self):
self.hp += 100
print('%s 使用了金疮药,血量增加到 %s' % (self.name, self.hp))
def attack(self,dog): #派生方法
dog.hp -= self.aggr
def get_weapon(self,weapon): #派生方法
if self.money >= weapon.price:
self.money -= weapon.price
self.weapon = weapon
self.aggr += weapon.aggr
else:
print('金币不足')
class Weapon:
def __init__(self,name,aggr,njd,price):
self.name = name
self.aggr = aggr
self.njd = njd
self.price = price
def hand18(self,person):
if self.njd > 0:
person.hp -= self.aggr*2
self.njd -= 1
else:
print("您的武器坏了")
gouzi = Dog('哮天犬',999,200,'taidi')
nezha = Person('哪吒',1999,300,'女',0)
print(gouzi.__dict__)
w = Weapon('打狗棒',200,3,998)
gouzi.eat()
nezha.eat()
print(gouzi.hp)
print(nezha.hp)
print(gouzi.__dict__)
#D:\python\python.exe F:/运维笔记/python/面向对象/017面向对象继承03方法一.py
{'name': '哮天犬', 'hp': 999, 'aggr': 200, 'kind': 'taidi'}
哮天犬 使用了金疮药,血量增加到 1099
哮天犬 使用了金疮药,增加两颗牙齿
哪吒 使用了金疮药,血量增加到 2099
1099
2099
{'name': '哮天犬', 'hp': 1099, 'aggr': 200, 'kind': 'taidi', 'teeth': 2}
# -*- coding: UTF-8 -*-
#super().__init__ 方法二调用父类
#super() 不仅可以再类的内部使用,也可以再类的外部使用
#super()内部使用: super().__init__(name,hp,aggr) #不需要传类名
#super()外部使用:super(Dog,gouzi).eat() #需要传类名字和对象名
class Animal:
def __init__(self,name,hp,aggr):
self.name = name
self.hp = hp
self.aggr = aggr
def eat(self):
self.hp += 100
print('%s 使用了金疮药,血量增加到 %s' % (self.name, self.hp))
class Dog(Animal):
def __init__(self,name,hp,aggr,kind):
super().__init__(name,hp,aggr)
self.kind = kind #派生属性
def eat(self):
Animal.eat(self) #如果既想使用父类原本的功能,也想实现新的功能,则需要在子类中调用父类
self.teeth = 2
self.hp += 100
print('%s 使用了金疮药,增加两颗牙齿' % (self.name))
def bite(self,person):
person.hp -= self.aggr
class Person(Animal):
def __init__(self,name,hp,aggr,sex,money):
Animal.__init__(self, name, hp, aggr)
#super().__init__(name,hp,aggr)
self.sex = sex #派生属性
self.money = 0 #派生属性
def eat(self):
self.hp += 100
print('%s 使用了金疮药,血量增加到 %s' % (self.name, self.hp))
def attack(self,dog): #派生方法
dog.hp -= self.aggr
def get_weapon(self,weapon): #派生方法
if self.money >= weapon.price:
self.money -= weapon.price
self.weapon = weapon
self.aggr += weapon.aggr
else:
print('金币不足')
class Weapon:
def __init__(self,name,aggr,njd,price):
self.name = name
self.aggr = aggr
self.njd = njd
self.price = price
def hand18(self,person):
if self.njd > 0:
person.hp -= self.aggr*2
self.njd -= 1
else:
print("您的武器坏了")
gouzi = Dog('哮天犬',999,200,'taidi')
nezha = Person('哪吒',1999,300,'女',0)
w = Weapon('打狗棒',200,3,998)
super(Dog,gouzi).eat() #在父类和子类都有相同方法,仅执行父类
print(gouzi.hp)
gouzi.eat() ##在父类和子类都有相同方法,父类和子类都执行
print(gouzi.hp)
#D:\python\python.exe F:/运维笔记/python/面向对象/017面向对象继承03方法二.py
哮天犬 使用了金疮药,血量增加到 1099
1099
哮天犬 使用了金疮药,血量增加到 1199
哮天犬 使用了金疮药,增加两颗牙齿
1299
多继承
多继承中:子类的对象调用一个方法,默认就近原则
新式类中:广度优先
经典类:深度优先
python2.7 新式类和经典类共存,新式类要继承object
python3 只有新式类,默认继承object
经典类和新式类还有一个区别:mro方法只在新式类中存在 super 只在python3中存在
类名.mro() 方法:查看广度优先的继承顺序
super本质:不是直接找父类,根据广度优先的继承顺序查找上一个类
python3:
实例:
print(D.mro()) #打印继承顺序
class F:
def func(self):print('F')
class A(F):pass
#def func(self):print('A')
class B(A):pass
#def func(self):print('B')
class E(F):#pass
def func(self):print('E')
class C(E):pass
#def func(self):print('C')
class D(B,C):pass
#def func(self):print('D')
d = D()
d.func()
print(D.mro())
D:\python\python.exe F:/运维笔记/python/面向对象/018面向对象继承03多继承.py
E
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.A'>, <class '__main__.C'>, <class '__main__.E'>, <class '__main__.F'>, <class 'object'>]
#super本质:不是直接父类,而是根据调用者的节点位置的广度优先顺序来的
#super本质:不是直接父类,而是根据调用者的节点位置的广度优先顺序来的
class A:
def func(self):
print('A')#9
class B(A):
def func(self):#5
super().func()#6
print('B')#11
class C(A):
def func(self):#7
super().func()#8
print('C')#10
class D(B,C):
def func(self): #3
super().func()#4
print('D')#12
d = D() #1
d.func()#2