今日主要内容:
类的复习
继承
多继承
一,昨日内容
类后面可以跟一个括号,也可以不跟
对象可以使用静态变量? True
类可以使用对象里的属性么? False
组合
一个类的对象是另外一个类对象的属性
什么有什么的关系
class A:
def __init__(self):
self.name = 'egon'
class B:
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
b = B(18, 1, 17)
a = A()
a.birth = b
print(a.birth.year)
输出结果:
18
二,继承
1,要点一
class A(object):
pass # 父类,基类,超类
class B:
pass # 父类,基类,超类
class AB_son(A, B):
pass # 子类,派生类
class A_son(A):
pass # 子类,派生类
# 一个类 可以被多个类继承
# 一个类 可以继承多个父类 ——只python里,其他语言没有多继承
print(A_son.__bases__) # 查看父类用的
print(AB_son.__bases__)
print(A.__bases__)
print(B.__bases__) # python3 -新式类# 没有继承父类默认继承object(老祖宗)
# 在python3中所有的类都有父类
输出结果:
(<class ‘main.A’>,)
(<class ‘main.A’>, <class ‘main.B’>)
(<class ‘object’>,)
(<class ‘object’>,)
2,要点二
class Animal:
def __init__(self, name, aggr, hp):
self.name = name
self.aggr = aggr
self.hp = hp
self.func()
def func(self):
print('执行Animal中的func')
class Dog(Animal):
def func(self):
print('执行Dog中的func')
def bite(self, person):
person.hp -= self.aggr
jin = Dog('金老板', 200, 500) # 这个地方究竟会执行Animal的func? 还是执行Dog的func?
print(jin.name)
输出结果:
执行Dog中的func
金老板
3,要点三
class Animal:
def __init__(self, name, aggr, hp):
self.name = name
self.aggr = aggr
self.hp = hp
def eat(self):
print('吃药回血')
self.hp += 100
class Dog(Animal):
def __init__(self, name, aggr, hp, kind):
Animal.__init__(self, name, aggr, hp)
self.kind = kind # 派生属性
def eat(self):
Animal.eat(self) # 如果既想实现新的功能也想使用父类原本的功能,还需要在子类中再调用父类
def bite(self, person): # 派生方法
person.hp -= self.aggr
class Person(Animal):
def __init__(self, name, aggr, hp, sex):
Animal.__init__(self, name, aggr, hp)
self.sex = sex # 派生属性(父类之中没有的,子类创建的就叫派生)
self.money = 0 # 派生属性
def attack(self, dog):
dog.hp -= self.aggr
jin = Dog('金老板', 100, 500, '吉娃娃')
jin.eat()
print(jin.hp)
alex = Person('alex', 1, 2, None)
alex.eat()
print(alex.hp)
jin.bite(alex)
print(alex.hp)
# 父类中没有的属性 在子类中出现 叫做派生属性
# 父类中没有的方法 在子类中出现 叫做派生方法
# 只要是子类的对象调用,子类中有的名字 一定用子类的,子类中没有才找父类的,如果父类也没有报错
# 如果父类 子类都有 用子类的
# 如果还想用父类的,单独调用父类的:
# 父类名.方法名 需要自己传self参数
# super().方法名 不需要自己传self
# 正常的代码中 单继承 === 减少了代码的重复
# 继承表达的是一种 子类是父类的关系
输出结果:
吃药回血
600
吃药回血
102
2
4,要点四
class Animal:
def __init__(self, name, aggr, hp):
self.name = name
self.aggr = aggr
self.hp = hp
def eat(self):
print('吃药回血')
self.hp += 100
class Dog(Animal):
def __init__(self, name, aggr, hp, kind):
super().__init__(name, aggr, hp) # 只在新式类中有,python3中所有类都是新式类
self.kind = kind # 派生属性
def eat(self):
print('dog eating')
jin = Dog('金老板', 200, 500, 'teddy')
print(jin.name)
jin.eat()
super(Dog, jin).eat()
# 区分两个eat分别来自于?
输出结果:
金老板
dog eating
吃药回血
三,多继承
1,要点一
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):
pass
d = D()
d.func()
输出结果:
A
2.要点二:广度优先
# coding:utf-8 钻石继承
# B-->A-->F
# C-->E-->F
class F:
def func(self):
print('F')
class A(F):
def func(self):
print('A')
class B(A):
pass
class E(F):
pass
class C(E):
def func(self):
print('C')
class D(B, C):
pass
d = D()
d.func()
print(B.mro())
# 先在深度方向找!至到找到 和广度相连接的那个元素。
# 新式类中的继承顺序 : 广度优先!广度优先!广度优先!
输出结果:
A
[<class ‘main.B’>, <class ‘main.A’>, <class ‘main.F’>, <class ‘object’>]
3,要点三
# 理解super的本质(记住钻石图)广度优先!!!!!!!
# D的super是B,B的super是C,C的super是A.
class A(object):
def func(self):
print('A')
class B(A):
def func(self):
super().func()
print('B')
class C(A):
def func(self):
super().func()
print('C')
class D(B, C):
def func(self):
super().func()
print('D')
d = D()
d.func()
# python2.7
# 新式类 继承object类的才是新式类------>广度优先
# 经典类 如果你直接创建一个类在2.7中就是经典类--------->深度优先
# 单继承 : 子类有的用子类 子类没有用父类
# 多继承中,我们子类的对象调用一个方法,默认是就近原则,找的顺序是什么?
# 经典类中 深度优先
# 新式类中 广度优先
# python2.7 新式类和经典类共存,新式类要继承object
# python3 只有新式类,默认继承object
# 经典类和新式类还有一个区别 mro方法只在新式类中存在
# super 只在python3中存在
# super的本质 :不是单纯找父类,而是根据调用者的节点位置的广度优先顺序来的.
输出结果:
A
C
B
D