07-1 | 类的继承和多态

逸兴
逸兴
逸兴
57
文章
25
评论
2020-05-2122:27:03
评论
1900字阅读6分20秒
摘要

python中类的继承和多态

第一章 类的继承

括号中写上继承的类的列表,就可以实现继承。

子类可以继承父类的一些方法和属性,减少代码冗余。

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

    @property
    def name(self):
        return self._name

    def shout(self):
        print('{} shouts'.format(self.__class__.__name__))


class Dog(Animal): pass  # Dog类继承 Animal
class Cat(Animal): pass

d = Dog('XiaoHei')
c = Cat('MiMi')

d.shout()   # 子类具有继承的父类的方法
c.shout()

print(d.name, c.name)   # # 子类具有继承的父类的属性
07-1 | 类的继承和多态

类可以单一继承,也可以多继承。多继承用逗号分开。

实例的类型是它的所属类。

类的特殊属性和方法

mro() 和 __mro__ 打印属性继承顺序

07-1 | 类的继承和多态
07-1 | 类的继承和多态

mro 打印属性继承顺序,其作用是一致的。区别是一个返回列表,一个返回元组。

__bases__ 和 __base__

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

    @property
    def name(self):
        return self._name

    def shout(self):
        print('{} shouts'.format(self.__class__.__name__))

class Tes: pass

class Dog(Animal): pass
class Cat(Animal, Tes): pass

d = Dog('XiaoHei')
c = Cat('MiMi')

d.shout()
c.shout()

print(d.name, c.name)

print(Animal.mro(), Animal.__mro__)
print(Dog.mro(), Dog.__mro__)
print(Cat.mro(), Cat.__mro__)
print('----------------------')

print(Animal.__bases__, Animal.__base__)   # __bases__ 显示所有继承的基类,元组显示
print(Cat.__bases__, Cat.__base__)   # __base__ 只显示继承的所有基类的第一个, 
07-1 | 类的继承和多态

object 是所有类的基类,python3中默认就是,不显示。

__subclasses__打印所有子类

07-1 | 类的继承和多态
07-1 | 类的继承和多态
07-1 | 类的继承和多态

继承中的访问控制

__a 私有类属性,私有成员。

self.__a 是有实例属性。

07-1 | 类的继承和多态

私有属性的改名规则:

重要的一点: 类中的私有属性写在哪个类里,名称会改为 _Class__name, 这种情况下即使被继承,属性名字也不会变化。

比如:

07-1 | 类的继承和多态
  • self.__a += 1
  • self.__a = self.__a + 1
  • self._Animal__a = self._Animal__a + 1, 而不是self._Cat__a
07-1 | 类的继承和多态

实例初始化时,会先执行子类的 __init__, 如果子类没有回执行父类的。

对于实例或者类中有的属性,通过__dict__可以很清晰的看到。

07-1 | 类的继承和多态
07-1 | 类的继承和多态

实例属性的查找顺序

实例.__dict__ , 实例的类.__dict__, 实例的类的父类.__dict__

上面内容在Animal类中定义了__a 即为_Animal___a, 而Animal被Cat继承, Cat实例化c。

c.showa()中,调用self.__a(实际是self._Animal__a),会先在实例c的属性中查找_Animal__a 查找不到在去 类Cat中查找_Animal__a 查找不到在继续去父类Animal中查找, 在Animal类中定义的_Animal__a 即使用。

第二章 覆盖、初始化和多态

什么是覆盖?

子类有和父类相同的属性,在子类的实例调用这个方法时,会优先在子类中查找,这样就达到了覆盖父类属性的效果。

07-1 | 类的继承和多态

子类中的同名方法,覆盖父类的同名方法。

只有子类的实例会被改变,父类的实例不受影响。

子类中调用父类的方法,而不是覆盖。

super() 调用父类中的方法。

07-1 | 类的继承和多态
07-1 | 类的继承和多态

调用的最近的父类的方法。

调用父类的__init__方法

07-1 | 类的继承和多态
07-1 | 类的继承和多态

父类A的__init__()中定义了私有属性__d, 即改名为_A__d, 此时子类B中调用了父类的__init__() 即便如此,__d依然为_A__d

07-1 | 类的继承和多态

单继承

07-1 | 类的继承和多态

多态

在子类和父类中,使用同一个接口,实现不同的表现。

就像上面的例子,在父类 Animal 中有shout方法,同时在子类 Cat 中也有shout方法,但是实现的效果却不同。

多态的前提:继承,覆盖




https://www.hugbg.com/archives/2558.html
逸兴
  • 本文由 发表于 2020-05-2122:27:03
  • 除非特殊声明,本站文章均为原创,转载请务必保留本文链接
01-1 数据类型 基础语法

01-1 数据类型

第一章 数据类型 使用type() 函数可以查看数据类型 1.1 字符串 str 字符串是使用单引号或双引号括起来的任意文本。 比如'abc', '123'等 字符串类型 字符串类型用str表示 st...
09-5 | asyncio基本使用 并发编程

09-5 | asyncio基本使用

第一节 关于asyncio asyncio 在3.4 版本中加入到标准库, asyncio基于selector实现, 看似库, 其实是个框架, 包含异步IO, 事件循环, 协程, 任务等内容。 通过a...
09-4 | 全局解释器锁 & 多进程 & 池 并发编程

09-4 | 全局解释器锁 & 多进程 & 池

GIL CPython 在解释器进程级别有一把锁,叫做GIL,即全局解释器锁。 GIL 保证CPython进程中,只有一个线程执行字节码。甚至是在多核CPU的情况下,也只允许同时只能 有一个CPU核心...
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: