继承 # 面向对象的三大特性之一:继承 # 继承:至少有两个类:什么是什么的关系,为了避免几个类之间有相同的代码 # 父类:Animal # 子类:Dog Person # 动物
class Animal: def __init__(self,name,aggressivity,life_value): self.name = name self.aggressivity = aggressivity self.life_value = life_value#狗class Dog(Animal): # 定义一个狗类 def bite(self,people): people.life_value -= self.aggressivity#人class Person(Animal): # 定义一个人类 def attack(self,dog): dog.life_value -= self.aggressivity def get_weapon(self,weapon_obj): if self.money > weapon_obj.price: self.money -= weapon_obj.price # 金老板花钱买武器 self.weapon = weapon_obj # 金老板装备打狗棒 self.aggressivity += weapon_obj.aggr # 金老板的攻击力增加了huang = Dog('大黄', 100, 3000) # __init__ 找父类print(huang.life_value)boss_gold = Person('金老板', 5, 250) # __init__ 自己没有 找父类print(boss_gold.life_value)# Dog.bite(Person)print(Dog.__bases__)print(Animal.__bases__)
# python中有两种类:经典类和新式类
# python3中是只有新式类---都默认继承object,class Animal(object) == class Animal: # python2经典类和新式类并存 # class Animal: -->是经典类 # class Animal(object):--->新式类 # class ParentClass1: #定义父类 # pass # # class ParentClass2: #定义父类 # pass # # class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass # pass # # class SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类 # pass # SubClass1.__bases__ #__base__只查看从左到右继承的第一个子类,__bases__则是查看所有继承的父类 小结: # 两个类中有相同的代码 # 继承:把相同的代码放在父类中,子类的对象在子类中没有找到方法的时候,会使用父类的 # 单继承和多继承 # 父类也称为超类或基类 # 子类又称为派生类 # 抽象和继承的关系:先抽象再继承
class Animal: def __init__(self, name,aggressivity,life_value): self.name = name self.aggressivity = aggressivity self.life_value = life_value def eat(self): self.life_value+=10class Dog(Animal): def __init__(self, name, breed, aggressivity, life_value): Animal.__init__(self,name,aggressivity,life_value) self.breed = breed #派生属性:父类没有的属性 def bite(self,people): #派生方法:父类没有的方法 people.life_value -= self.aggressivity#人class Person(Animal): def __init__(self, name, aggressivity, life_value, money): # Animal.__init__(self,name,aggressivity,life_value) super().__init__(name,aggressivity,life_value) #新式类 self.money = money #派生属性:父类没有的属性 def attack(self,dog): #派生方法:父类没有的方法 dog.life_value -= self.aggressivity def get_weapon(self,weapon_obj): if self.money > weapon_obj.price: self.money -= weapon_obj.price # 金老板花钱买武器 self.weapon = weapon_obj # 金老板装备打狗棒 self.aggressivity += weapon_obj.aggr # 金老板的攻击力增加了snoopy= Dog('太白','京巴',250,500)print(snoopy.name)print(snoopy.breed)snoopy.eat()print(snoopy.life_value)super(Dog,snoopy).eat() #Animal.eat(snoopy)print(snoopy.life_value)
派生属性:在自己的init方法里 使用父类的init方法 ---指名道姓调用方法 # 派生方法:在子类中增加父类没有的 # 只要子类有,就用子类的属性或方法 # 只要想用父类的,就用Animal.eat(snoopy) 父类名.父类的方法(子类对象) ---这是2.7经典类中的调用方法 # 在新式类中需要使用super方法 super(子类名,子类对象).方法名() 类内可以省略super的参数 --这是新式类中的 # 用子类的对象,调用父类的方法: # 如果子类中没有这个方法,直接使用父类的 # 如果子类中有与父类同名的方法: # 经典类:指名道姓调用 类名.方法名(子类对象) 类内外一致 # 新式类:使用super方法,super(子类名,子类对象).方法名() 类内可以省略super的参数
面试题:
钻石继承问题
# 本小节的环境是在python2.7中# 经典类和新式类的多继承问题,继承顺序问题# 经典类:博大精深,所以经典类就是深度优先,先往深处找# 新式类:广度优先class F(object): pass def f(self): print('F')class E(F): pass def f(self): print('E')class D(F): pass # def f(self): # print('D')class B(D): pass # def f(self): # print('B')class C(E): pass def f(self): print('C')class A(B,C): pass # def f(self): # print('A')a = A()a.f()print(A.mro()) #新式类:查看继承顺序# class A(object):pass #新式类# py3 —— 广度优先# py2 —— 新式类#面试 —— 能对应 新式类 是广度优先 经典类是深度优先
多态
#python不支持多态的class Animal:passclass Person(Animal): def attack(self): passclass Dog(Animal): def attack(self): passdef attack(obj): #多态 obj.attack()d = Dog()p = Person()attack(d) #d.attack()attack(p) #p.attack()print(10)#鸭子类型 list tuple是一对鸭子类型#列表#元组# 切片 : 字符串 列表 元组# + :字符串 列表 数字def len(l):pass