单继承,多继承,菱形继承---day21

1.单继承

# ### 继承:一个类除了自身所有用的属性方法之外,还获取了另外一个类的成员属性和方法
'''
一个类继承另外一个类,那么该类就是子类(衍生类),被继承的这个类就叫做父类(基类,超类)
继承:
    (1)单继承 (2)多继承
python 所有的类都默认继承父类 object
'''

# ### 单继承
class Human(object):
    hair =  '金色'
    sex = ''
    
    def eat(self):
        print('人类天生就喜欢吃吃吃')
        
    def __makebaby(self):
        print("人类天生就能够繁衍后代")
        
#(1) 子父类继承之后,子类可以调用父类所有的公有成员
class Man(Human): #class Man(父类)
    pass

obj = Man()  #Man(构造方法的参数)
print(obj.hair) #金色

#(2) 子父类继承之后,子类不可以调用父类的私有成员
class Woman(Human):
    def pub_makebaby(self):
        self.__makebaby

obj = Woman()
obj.eat()
#obj.__makebaby()  不行
#obj.pub_makebaby() 不行


#(3) 子父继承之后,子类可以重写父类的同名方法
'''
子父继承之后
如果子类里面有该成员属性方法,优先调用自己的
如果没有该成员,name调用父类的公有成员
如果都没有,直接报错
'''
class Children(Human):
    sex = '女性'
    def eat(self):
        print("小孩下生只能吃奶奶")
obj = Children()
print(obj.sex)
obj.eat()

2.多继承

# ### 多继承

#(1) 基本语法
class Father():
    property = "玉树临风,风流倜傥,一枝梨花压海棠"
    def f_hobby(self):
        print("吃喝嫖赌抽,坑蒙拐骗偷,抽烟喝酒烫头")
        
class Mother():
    property = "沉鱼落雁,闭月羞花,一枝红杏出墙来"
    def m_hobby(self):
        print("打麻将,敷面膜,跳广场舞")
        
class Daughter(Mother,Father):
    pass
    
#实例化对象
obj = Daughter()
print(obj.property)
obj.m_hobby()


#(2) super用法
'''
(1)super本身就是一个类 super()是一个对象 用于调用父类的绑定方法
(2)super() 只应用在绑定方法中,默认自动传递self对象(前提super所在作用域存在self)
(3)super用途:解决复杂的多继承调用顺序
'''

class Father():
    property = "玉树临风,风流倜傥,一枝梨花压海棠"
    def f_hobby():
        print("吃喝嫖赌抽,坑蒙拐骗偷,抽烟喝酒烫头")
        
class Mother():
    property = "沉鱼落雁,闭月羞花,一枝红杏出墙来"
    
    #1.利用类来调用父类的成员
    def skill1(self):
        print(Mother.property)
        Father.f_hobby()
        
    #2.利用对象调用父类的属性和方法
    '''self在调用父类成员的时候,如果本类中里有,先调用自己的,没有,再调用父类的'''
    def skill2(self):
        self.m_hobby()
        print(self.property)

#3.利用super调用父类的属性和方法
'''
    super() 只调用父类的相关公有成员,不会调用自己本类的成员,父类也没有的话,直接报错
    super() 特指只调用父类,和self不同
'''
def skill3(self):
    print(super())
    print(super().property) #玉树临风,风流倜傥,一枝梨花压海棠
    super().m_hobby()
    
    #super() 调用方法时,必须是绑定方法,默认传递该类的对象
    #super().f_hobby()
    
obj =Son()
obj.skill1()
obj.skill2

obj.skill3()

3.菱形继承

# ### 菱形继承
'''
    Human
Man      Woman
    Children
'''

class BigMan():
    pass

class Human():
    pty = 4
    def feelT(self):
        #self  此刻接受的是Children的对象
        print("原始人类天热了,让后裔把太阳射下来1")
        print(self.pty)  #obj.pty = 1
        print("原始人类天冷了,让女娲补天,防止漏风2")
        
class Man(Human):
    pty = 3
    def feelT(self):
        #self 此刻接受的是Children的对象
        print("现代男人天热了,吹吹空调3")
        super().feelT()
        print("现代男人天冷了,吹暖气4")
        
class Woman(Human):
    pty = 2
    def feelT(self):
        # self 此刻接受的是Children的对象
        print("现代女人天热了,洗洗澡5")
        super().feelT()
        print("现代男人天冷了,吃雪糕6")

class Children(Man,Woman):
    pty = 1
    def feelT(self):
        print("现代小朋友天热了,洗海澡7")
        #super() 调用方法时候,会携带当前类的对象进行传递
        super().feelT()
        print("现代小朋友天冷了,钻被窝8")
obj = Children()
obj.feelT()


# mro 列表: super用途的体现 解决复杂的多继承调用顺序
'''
类.mro() 返回的是方法调用顺序的列表,针对于多继承下的同名方法,按照列表的顺序依次调用
'''
'''
[<class '__main__.Children'>, <class '__main__.Man'>, <class '__main__.Woman'>, <class '__main__.Human'>, <class 'object'>]
'''
lst = Children.mro()
print(lst)


# issubclass 判断是否存在子父类系(语法使用跟isinstance的使用一模一样)
'''只要在一个继承链上即可(有血缘关系即可),应用范围在类的身上'''
res = issubclass(Children,Man)
res = issubclass(Children,Woman)
res = issubclass(Children,Human)
res = issubclass(Children,BigMan)
res = issubclass(Children , (Man,Woman,Human,BigMan))
print(res)

#isinstance 判断类型
"""只要在一个继承链上即可(有血缘关系即可),是在判断对象和类之间的关系"""
res = isinstance(obj,Children)
res = isinstance(obj,Man)
res = isinstance(obj,Woman)
res = isinstance(obj,BigMan) # False
print(res)

print(Children.__dict__)

#in 判断在或者不在 在=> True 不在False
res = "feelT" in Children.__dict__
print(res) #True

总结:

继承 一个类除了自身所用的属性方法之外,还获取了另外一个类的成员属性和方法
继承又分为单继承 多继承  菱形继承
单继承
就是一个类继承另外一个类,那么该类就是子类,被继承的这个类就叫做父类
子类继承父类后,子类可以调用父类所有的公有成员,但是不可以调用父类的私有成员
如果子类的方法跟父类的方法同名,但是就想用自己的,那么就可以重写父类的同名方法
会优先调用自己类中的成员


多继承 就相当于子类继承多个父类
super超继承的用法 意思就是子类有的,父类也有,但是我又想用父类的,同时还要保留自己类的特性,
那么就可以用super超继承
super本身就是一个类,super()是一个对象,用于调用父类的绑定方法
只应用在绑定方法中,默认会自动传递self对象前提super所在的作用域存在self
只会调用父类的相关公有成员,不会调用自己本类的成员,要是父类也没有 就报错


菱形继承:
当一个子类继承多个父类时,多个父类最终继承了同一个类,称之为菱形继承
继承原理:
python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,
这个MRO列表就是一个简单的所有基类的线性顺序列表,例如
__mro__查看继承查找
所有父类的MRO列表并遵循如下三条准则:
1.子类会先于父类被检查
2.多个父类会根据它们在列表中的顺序被检查
3.如果对下一个类存在两个合法的选择,选择第一个父类