python基础day33 单继承和多继承下的属性查找和组合

单继承下的属性查找

# 单继承的意思是一个类只继承一个类
class D():
    pass

class C(D):
    pass

class B(C):
    pass

class A(B):
    pass

"""python支持多继承"""
class D():
    pass

class C(D):
    pass

class B(C):
    pass

class A(B,C,D):
    pass

# 如何查找继承下的属性和方法呢class Foo():    def f1(self):        print("Foo.f1")    def f2(self):        obj:        print("Foo.f2")        self.f1()class Bar(Foo):    def f1(self):        print("Bar.f1")


# """单继承下的属性查找顺序:先从对象自己的名称空间中查找,然后去产生这个对象的类中查找,最后在去继承的父类中查找"""obj = Bar()obj.f2()  # obj.f2(obj)




class Foo():
    def __f1(self):  # _Foo__f1()
        print("Foo.f1")

    def f2(self):
        # obj:
        print("Foo.f2")
        self.__f1()  # self._Foo__f1()


class Bar(Foo):
    def __f1(self):    # _Bar__f1()
        print("Bar.f1")


"""单继承下的属性查找顺序:先从对象自己的名称空间中查找,然后去产生这个对象的类中查找,最后在去继承的父类中查找"""
obj = Bar()
obj.f2()  # obj.f2(obj)

多继承下的属性查找

# 一个类可以继承多个类
"""python支持多继承"""
class D():
    pass

class C(D):
    pass

class B(C, D):
    pass

class A(B,C,D):
    pass

多继承下的属性查找分为:

菱形查找:

 

非菱形查找:

 

菱形查找分:经典类和新式类

经典类:按照深度优先查询

新式类:按照广度优先查询

ps:在python3中都是新式类,所以多继承下的属性查找,如果属性找不到,就按照广度优先查询

一般情况下,最好不要使用多继承

drf中的多继承很好明白

 

super关键字的使用

class A:
    def test(self):
        super().test()


class B:
    def test(self):
        print('from B')


class C(A, B):
    pass


# c = C()
# c.test()  # from B
a = A()
a.test()

mro列表

mro列表就是C类的属性查找顺序

ps:如果你继承的类中出现了super()关键字的用法,就要使用mro列表来查找属性

print(C.mro())  # [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
print(A.mro())  # [<class '__main__.A'>, <class 'object'>]
print(A.__mro__)

多态和多态性(理论)

多态:一种事物的多种形态

eg:
水:液态水、气态水、固态水
动物:人、狗、猫、猪...

# 如何在父类里面强制限制子类中必须有speak功能

class Animal():
    def speak():
        pass

class People(Animal):
    def speak():
        pass

class Dog(Animal):
    def speak():
        pass

class Pig(Animal):
    def speak():
        pass

obj = People()
obj.speak()

# 强制限制

 import abc  # abstract 抽象的

# 这个类就变成了:抽象类
# 抽象类的特点:只能被继承,不能被实例化!
# 抽象类中的方法都是抽象方法,而抽象方法不再实现具体的功能,而是用来限制子类的行为
"""强制限制,这种方式是python不推荐的,python推荐的是鸭子类型"""

class Animal(metaclass=abc.ABCMeta):
    @abc.abstractmethod  # 抽象方法
    def speak(self):
        pass

    @abc.abstractmethod
    def jiao(self):
        pass


class People(Animal):
    def speak(self):
        pass
    ...

class Dog(Animal):
    def speak(self):
        pass

class Pig(Animal):
    def speak(self):
        pass

obj = People()
obj1 = Dog()
obj.speak()
obj1.speak()

组合

# 组合它不是一个新技术,就是之前我们学习的知识点
组合:就是一个对象拥有一个属性,该属性的值是另外一个对象
class Foo():
    def __init__(self, m):
        self.m = m



class Bar():
    def __init__(self, n):
        self.n = n


obj = Foo(10)
obj1 = Bar(20)

"""obj对象就是一个超级对象,通过一个对象可以得到另外一个对象的值"""
obj.x = obj1
# obj.x ---------> obj1
print(obj1.n)
# print(obj.x.n)
print(obj.x.n)  # print(obj1.n)

class People():
    def __init__(self, name, age, gender):
        """这个是指名道姓的调用方法,不依赖于继承"""
        self.name = name
        self.age = age
        self.gender = gender

"""
继承一般用在什么是什么的时候
组合一般用在什么有什么的时候
"""
class Course():
    def __init__(self, course_name, course_price, course_period):
        """这个是指名道姓的调用方法,不依赖于继承"""
        self.course_name = course_name
        self.course_price = course_price
        self.course_period = course_period

python=Course("python", 10000, '6mon')
linux = Course("linux", 20000, '5mon')


class Student(People):
    def __init__(self, name, age, gender, course=None):
        if course is None:
            course = []
        """这个是指名道姓的调用方法,不依赖于继承"""
        super(Student, self).__init__( name, age, gender)
        self.courses = course
    def choose_course(self):
        pass


stu = Student('kevin', '19', 'male')
# print(stu.course_name)
# print(stu.course_price)

stu.courses.append(python) # stu.courses ====> [python对象]
stu.courses.append(linux) # stu.courses ====> [python对象, linux对象]
print(stu.courses)

 

posted @ 2023-06-27 16:41  吼尼尼痛  阅读(14)  评论(0编辑  收藏  举报