类与类的关系

从类空间与对象空间的角度研究类

给对象封装属性:

1.在__init__中

2.在类的外部

3.在类的其他方法中

给一个类添加属性:

1.类的外部

2.类的内部

class A:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def func(self,sex):
        self.sex = sex
    def func1(self):
        A.country = '中国'

#给对象添加属性:
obj = A('barry',18)           #在__init__中添加属性
obj.height = 176              #在类的外面添加属性
obj.func('')                #在类的方法中添加属性
print(obj.__dict__)

#给类添加属性:
A.count = 666                  #在类的外部
obj.func1()                    #在类的内部

类对象指针(对象空间):

对象找属性顺序:对象空间--类空间--父类空间

类指针(累空间):

类找属性顺序:类空间--父类空间

以上顺序单向不可逆

类与类的关系

1.依赖关系 :  将一个类的类名或者对象传入到另一个类的方法中

class Elephant:                                     #大象类
    def __init__(self,name):
        self.name = name
    def open(self,ref):
        print('%s打开冰箱门'%(self.name))
        ref.beopen_door()
    def close(self,foo):
        print('%s关闭冰箱门'%(self.name))
        foo.beclosed_door()

class Refrigerator:                                 #冰箱类
    def __init__(self,name):
        self.name = name
    def beopen_door(self):
        print('%s冰箱门被打开了'%(self.name))
    def beclosed_door(self):
        print('%s冰箱门被关闭了'%(self.name))
   
ele = Elephant('猛犸')                          #实例化大象对象

haier = Refrigerator('海尔')                    #实例化冰箱对象
ele.open(haier)                                 #将冰箱对象传入大象类的方法中
ele.close(haier)

# gree = Refrigerator('格力')
# ele.open(gree)
# ele.close(gree)

#大象是主体,可以选择冰箱,冰箱依赖于大象

2.组合(关联,聚合)关系 : 将一个类的对象或者类名封装到另一个类的对象的属性中

class Boy:
    def __init__(self,name,girlfriend=None):
        self.name = name
        self.girlfriend = girlfriend
    def dinner(self,ref):
        if self.girlfriend:
            print('%s和女朋友%s共进晚餐'%(self.name,ref.name))
        else:
            print('今晚吃鸡,大吉大利')

class Girl:
    def __init__(self,name,boyfriend=None):
        self.name = name
        self.boyfriend = boyfriend
    def shopping(self,ref):
        if self.boyfriend:
            print('%s和男朋友%s一起逛街'%(self.name,ref.name))
        else:
            print('宅在家')

# alex = Boy('alex')          #girlfiend 默认为None
# alex.dinner()

结果:
今晚吃鸡,大吉大利                #执行else条件下语句

# ruhua = Girl('如花')
# alex.girlfriend = ruhua        #将ruhua这个对象传给girlfriend
# alex.dinner()

结果:
alex和女朋友如花共进晚餐

# jinlian = Girl('金莲')
# wuda = Boy('武大',jinlian)       #将jinlian这个对象在一开始就传给girlfriend
# wuda.dinner()

结果:
武大和女朋友金莲共进晚餐

# wuda.girlfriend = None
# wuda.dinner()                    #解除绑定

结果:
今晚吃鸡,大吉大利


# alex = Boy('alex')
# ruhua = Girl('如花')
# ruhua.boyfriend = alex      #将alex这个对象传给boyfriend
# ruhua.shopping()

结果:
如花和男朋友alex一起逛街

3.继承(实现)关系 : 有父类和子类,子类可以继承调用父类的内容

继承的好处:

1.减少代码重复率

2.让类与类产生关系,增强耦合性

3.使代码更加规范化,清晰化

在python3中,所有的类都默认继承父类 object

单继承

class Animal:
    live = '活着'
    def __init__(self,name,sex,age):
        self.name = name
        self.sex = sex
        self.age = age
    def eat(self):
        print('动物都会吃')

class Person(Animal):           #子类名(父类名)
    live = '无所谓'


对象:
p1 = Person('alex','',20)      #子类中没有,执行父类中的__init__
p1.eat()                              #子类中没有,执行父类中的eat方法
print(p1.live)                       #子类和父类中具有相同的属性,先调用自己类中的属性

结果:
无所谓


#子类执行父类的属性和方法,也会将自己的地址传给self

类名:
Person.live      #自己类中有,调用自己类中的属性

结果:
无所谓

对象既要执行子类的方法,又要执行父类的方法:

1.在子类中写入 父类名.方法名(self,参数) 

class Animal:
    live = '活着'
    def __init__(self,name,sex,age):
        self.name = name
        self.sex = sex
        self.age = age
    def eat(self):
        print('动物都会吃')

class Person(Animal):
    live = '无所谓'
    def eat(self):
        Animal.eat(self)            #父类名.方法名(self),手动将p1对象传给self
        print('人类都需要吃饭')

2.在子类的方法中,写入 super().方法名(参数)  自动将子类的对象传入父类方法的self

class Animal:
    def __init__(self,name,sex,age):
        self.name = name
        self.sex = sex
        self.age = age
    def eat(self):
        print('动物都会吃')

class Person(Animal):
    def eat(self):
        super().eat()            #调用父类的eat方法,将p1对象自动传给父类eat方法中的self
        print('人类都需要吃饭')

p1 = Person('alex','',20)  #自动调用父类的__init__方法进行传参
p1.eat()

结果:
动物都会吃
人类都需要吃饭

在子类中封装另外的属性

1.使用类名   不依赖继承

class Animal:
    def __init__(self,name,sex,age):
        self.name = name
        self.sex = sex
        self.age = age

class Person(Animal):
    def __init__(self,n,s,a,mind):
        # Animal.__init__(self,n,s,a)    #方法一:不依赖继承  类名后可以不加Animal
        self.mind = mind

p1 = Person('邓哥','',18,'思想')

2.super()    依赖继承

class Animal:
    def __init__(self,name,sex,age):
        self.name = name
        self.sex = sex
        self.age = ageclass Cat(Animal):
    def __init__(self,n,s,a,climb):
        super().__init__(n,s,a)          #方法二:依赖继承
        self.climb = climb

c1 = Cat('大橘','',4,'爬树')

 多继承

多继承的顺序:从左到右

类的分类:

python2x版本:(python2.2之前,只有经典类,python2.2之后出现了新式类)

经典类: 不继承object,多继承遵循深度优先

   深度优先:从左到右一条路走到底,没有再继续返回走下一条

新式类 : 继承object的类,多继承遵循c3算法 mro方法查询继承顺序

python3x版本:所有类都默认继承object  只有新式类

mro序列

表头和表尾:

[A,B,C]   表头:A    表尾:B,C

[A]         表头:A     表尾:空

[A] +[B] = [A,B]

merge里面的计算顺序(面试题):

merge([A,O], [C,E,F,O],[C])               #将第一个列表的第一个元素A提取出来,判断这个元素在其他表尾中存不存在,不重复,就单独提取出来
= [A] + merge([O], [C,E,F,O],[C])         #继续提取第一个元素O,跟第二个列表的表尾重复,不进行操作,继续找下一个列表的首个元素C进行判断
= [A,C] + merge([O], [E,F,O])           
= [A,C,E] + merge([O], [F,O])
= [A,C,E,F,O]
#练习
class O:
    pass

class D(O):
    pass

class E(O):
    pass

class F(O):
    pass

class B(D,E):
    pass

class C(E,F):
    pass

class A(B,C):
    pass

obj = A()
#按照merge的顺序,可以一步一步推算
mro(A(B,C)) = [A] + merge(mro(B),mro(C),[B,C])                 #A继承B,C   计算A的继承顺序的固定格式 

mro(B) = mro(B(D,E)) = [B] + merge(mro(D),mro(E),[D,E])        #B继承D,E
mro(D(O)) = [D,O]                                              #D继承O
mro(E(O)) = [E,O]                                              #E继承O

mro(B(D,E)) = [B] + merge([D,O],[E,O],[D,E])
             = [B,D] + merge([O],[E,O],[E])
             = [B,D,E,O]

mro(C) = mro(C(E,F)) = [C] + merge(mro(E),mro(F),[E,F])        #C继承E,F
mro(C) = mro(C(E,F)) = [C] + merge([E,O],[F,O],[E,F])         
                       = [C,E] + merge([O],[F,O],[F])
                       = [C,E,F] + merge([O],[O])
                       = [C,E,F,O] 
                       
mro(A(B,C)) = [A] + merge([B,D,E,O],[C,E,F,O],[B,C])        #整合计算
             = [A,B] + merge([D,E,O],[C,E,F,O],[C])
             = [A,B,D] + merge([E,O],[C,E,F,O],[C])
             = [A,B,D,C] + merge([E,O],[E,F,O])
             = [A,B,D,C,E] + merge([O],[F,O])
             = [A,B,D,C,E,F] + merge([O],[O])
             = [A,B,D,C,E,F,O] 

在python方法中,也可以直接输出打印:

print(A.mro())    

结果:[<class '__main__.A'>, <class '__main__.B'>, <class '__main__.D'>, <class '__main__.C'>, <class '__main__.E'>, <class '__main__.F'>, <class '__main__.O'>, <class 'object'>]    

#和上边计算的结果一样
原文地址:https://www.cnblogs.com/sandy-123/p/10320315.html