面向对象: 类与类之间的关系

一 依赖关系 (主从之分)

将一个类的名字或者对象传入另一个类的方法中

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)	

依赖与组合让类与类产生关系, 增强耦合性.

三 继承关系

继承者: 子类,派生类

被继承者: 父类, 基类, 超类

继承的优点:

  1. 增加了类的耦合性(耦合性不宜多,宜精)
  2. 减少了重复代码
  3. 使得代码更加规范化,合理化

3.1 继承的分类

继承可分为单继承和多继承

python2:

  1. 经典类:在python2.2之前,使用的是经典类,不写object不会继承object
  2. 新式类:在python2.2之后出现了新式类,不写object也会继承object

python3:

  1. 使用的都是新式类

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()
  1. 执行顺序:

    实例化对象时必须执行__init__方法,类中没有,从父类找,父类没有,从object类中找。先要执行自己类中的方法,自己类没有才能执行父类中的方法。

  2. 同时执行类以及父类方法:

    方法一: 不依赖继承 (用类名调用)

    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())

posted on 2019-11-05 21:57  Lav3nder  阅读(296)  评论(0编辑  收藏  举报