Atopos

导航

继承与多态

1.继承

image

1.1继承的概念

image

1.1.1什么是继承
    继承就是新建类的一种方式
    新建的类我们称之为子类或者叫派生类
    被继承的类称为父类或者基类
    
    子类继承父类就可以使用父类中的属性或方法
可以通过类的内置属性__bases__查看类继承的所有父类

1.1.2为什么要用继承
    类解决了对象与对象之间的代码冗余问题
    继承解决的是类与类之间的代码冗余问题

1.1.3如何使用继承
    新式类:
	继承了object类的子子孙孙类都是新式类
    经典类:
	没有继承了object类的子子孙孙的类就是经典类

1.2类的继承示例

image

class People():
    school = 'SH'

    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender


class Student(People):

    def __init__(self, name, age, gender, course=None):
        if course is None:
            course = []
        People.__init__(self, name, age, gender)
        self.courses = course

    def choose_course(self, course):
        self.courses.append(course)
        print('%s 选课成功 %s' % (self.name, self.courses))



obj = Student('ly', 19, 'male')


class Teacher(People):

    def __init__(self, name, age, gender, level):
        self.level = level
        People.__init__(self, name, age, gender)

    def score(self, obj, score):
        obj.score = score  # 给学生打分
        print('%s给%s打了%s分' % (self.name, obj.name, score))


tea = Teacher('ly', 19, 'male', 10)
print(tea.name)
print(tea.level)
tea.score(obj, 90)

1.3单继承下属性查找示例

image

# 在继承关系中,属性的查找顺序:
对象在查找属性时,先从对象自己的__dict__中找
如果没有则去产生对象的类中找,然后再去继承的父类中找


class C:
    x = 333

class B(C):
    x = 222

class A(B):
    x = 111

obj = A()
print(obj.x)
# 111

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

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

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

1.4多继承下属性查找示例

image

# 菱形继承:一个子类继承的多条分支最终汇聚一个非object的类上
# 在python3中是新式类

# 新式类:按照广度优先查询(继承了object的类)
# 经典类:按照深度优先查询(非继承object的类)
class A(object):
    def test(self):
        print('from A')


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

class C(A):
     def test(self):
         print('from C')
   


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

class E(C):
     def test(self):
         print('from E')
 


class F(D, E):
     def test(self):
         print('from F')
    

f1 = F()
print(F.mro())
# [<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
f1.test()  # 查找的顺序:F-->D-->B-->E-->C-->A-->object
# from F

1.5隐藏属性示例

image

# 父类如果不想让子类覆盖自己的方法
# 可以采用双下划线开头的方式将方法设置为私有的
class Foo:
    def __f1(self):  # _Foo__f1()
        print('Foo.f1')

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


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


obj = Bar()  # {}
obj.f2()

1.5super()和mro列表

image

super()函数是用于调用父类的一个方法
super()是用来解决多重继承问题的,直接用类名调用父类方法 python2中super(Class,self).方法名
python3中可以直接使用super().方法名()
super()返回的是一个特殊的对象,该对象会参考发起属性查找的那一个类的mro列表,去当前的父类中找属性,严格依赖继承

查找顺序涉及到mro()列表
mro是一种在多重继承中用于确定方法搜索顺序的一种算法,成为C3线性算法
Class.mro()

class People():
    school = 'SH'

    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender

class Teacher(People):

    def __init__(self, name, age, gender, level):
        self.level = level
        super().__init__(name, age, gender) # super的使用


# mro列表练习1
class A:
    def test(self):
        print('from A.test')
        super().test()


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


class C(A, B):
    pass


c = C()
c.test()


# mro列表练习2 
class B:
    def test(self):
        print('B---->test')

    def aaa(self):
        print('B---->aaa')

class A:
    def test(self):
        print('A---->test')
        super().aaa()


class C(A, B):
    def aaa(self):
        print('C----->aaa')


c = A()
# c.test()  # 打印结果:
print(A.mro())

2.多态与多态性

image

多态是指一类事物有多种状态

多态性指的是可以在不用考虑对象具体类型的情况下而直接使用对象,这就需要在设计时,把对象的使用方法统一成一种

# 抽象类: 抽象类只能被继承,不能被实例化
class Animal(metaclass=abc.ABCMeta):

    @abc.abstractmethod  # 该方法已经是抽象方法了
    def speak(self): pass

    @abc.abstractmethod
    def login(self):pass

class People(Animal):
    def speak(self):
        # print('嗷嗷嗷')
        pass
    def login(self):
        pass


class Pig(Animal):
    def speak(self):
        print('哼哼哼')


class Dog(Animal):
    def speak(self):
        print('汪汪汪')


obj = People()
obj.speak()

# 多态带来的特性:在不用考虑对象数据类型的情况下,直接调用对应的函数

def animal(animal):
    return animal.speak()

animal(obj)
animal(obj1)
animal(obj2)
animal(obj3)

# 父类限制子类的行为
class Animal():
    def speak(self):
        raise Exception("必须实现speak方法")

image

posted on 2021-12-06 20:52  Atopos_q  阅读(10)  评论(0编辑  收藏  举报