面向对象: 类与类之间的关系
一 依赖关系 (主从之分)
将一个类的名字或者对象传入另一个类的方法中
class Elephant:
def __init__(self,name):
self.name = name
def open(self,obj):
print(f'{self.name}开门')
obj.be_open()
class Refrigerater:
def __init__(self,name):
self.name = name
def be_open(self):
print(f'{self.name}门开了')
qiqi = Elephant('琪琪')
haier = Refrigerater('海尔')
qiqi.open(haier)
二 组合关系
将一个类的对象封装到另一个类的对象的属性中
class GameRole:
def __init__(self,name,ad,hp):
self.name = name
self.ad = ad
self.hp = hp
def equipment_weapon(self,weapon):
self.weapon = weapon
class Weapon:
def __init__(self,name,ad):
self.name = name
self.ad = ad
def weapon_attack(self,p1,p2):
p2.hp -= self.ad
print(f'{p1.name}使用{self.name}给了{p2.name}一下子,{p2.name}掉了{self.ad}滴血,还剩{p2.hp}滴血')
galun = GameRole('盖伦',10,100)
yasuo = GameRole('压缩',20,80)
sword = Weapon('大宝剑',15)
dao = Weapon('武士刀',25)
galun.equipment_weapon(sword)
yasuo.equipment_weapon(dao)
galun.weapon.weapon_attack(galun,yasuo)
yasuo.weapon.weapon_attack(yasuo,galun)
依赖与组合让类与类产生关系, 增强耦合性.
三 继承关系
继承者: 子类,派生类
被继承者: 父类, 基类, 超类
继承的优点:
- 增加了类的耦合性(耦合性不宜多,宜精)
- 减少了重复代码
- 使得代码更加规范化,合理化
3.1 继承的分类
继承可分为单继承和多继承
python2:
- 经典类:在python2.2之前,使用的是经典类,不写object不会继承object
- 新式类:在python2.2之后出现了新式类,不写object也会继承object
python3:
- 使用的都是新式类
3.2 单继承
class Aniaml(object):
type_name = '动物类'
def __init__(self,name,sex,age):
self.name = name
self.age = age
self.sex = sex
def eat(self):
print(self)
print('吃东西')
class Person(Aniaml):
pass
# 类名:
print(Person.type_name) # 可以调用父类的属性,方法。
Person.eat(111)
print(Person.type_name)
# 对象:
p1 = Person('春哥','男',18) # 实例化对象
print(p1.__dict__)
# 对象执行类的父类的属性,方法。
print(p1.type_name)
p1.type_name = '666'
print(p1)
p1.eat()
-
执行顺序:
实例化对象时必须执行__init__方法,类中没有,从父类找,父类没有,从object类中找。先要执行自己类中的方法,自己类没有才能执行父类中的方法。
-
同时执行类以及父类方法:
方法一: 不依赖继承 (用类名调用)
class Animal: def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex def eat(self): print('动物都会吃东西') class Human(Animal): def __init__(self,name,age,sex,hobby): Animal.__init__(self,name,age,sex) self.hobby = hobby def eat(self): Animal.eat(self) print(f'{self.name}会吃饭') person = Human('王洋',18,'男','女人') print(person.name) person.eat()
方法二: 依赖继承 super()
class Animal: def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex def eat(self): print('动物都会吃东西') class Human(Animal): def __init__(self,name,age,sex,hobby): # super(Human,self).__init__(name, sex, age) super().__init__(name,age,sex) self.hobby = hobby def eat(self): super().eat() print(f'{self.name}会吃饭') person = Human('王洋',18,'男','女人') print(person.name) person.eat()
super的作用: 重构父类的方法
super() 严格按照mro算法的执行顺序去执行
class A: a = 1 def func(self): print('in A') class B: b = 2 def func(self): print('in B') class C(A, B): def func(self): super(A, self).func() # 按照self对象从属于类的mro的顺序,执行A类的下一个类. print('in C') c1 = C() c1.func() # in B # in C
super(A,self) 从A开始往后查找 , 因此跳过了A 直接查B
3.3 多继承
1. 经典类:
遵循深度优先原则,从左往右查找
2. 新式类:
遵循c3算法
mro序列: mro(A(B,C)) = [A] + merge(mro(B),mro(C),[B,C])
如果只继承一个父类:class B(A)
mro(B) = mro(B(A)) = [B,A]
查询方法: print(A.mro())