面向对象三大特性之继承与派生

一、简介

'''
什么是继承
    继承是一种新建类的方式,新建的类称为子类或者派生类,被继承的类称为父类或基类或超类
    子类会继承父类的属性,从而解决代码重用问题
    Python支持多继承
    注意:
        在Python3中,如果没有显示继承任何类,默认继承object类
        object类提供了一些基础的功能
        print(Fclass1.__bases__)
        (<class 'object'>,)
        在Python2中,如果没有显示的继承任何类,也不会继承object类
        print(Fclass1.__bases__)
        ()

    在Python中类分为两种
    新式类:
        但凡继承object的类,以及该类的子类都是新式类
        在Python3中所有的类都是新式类
    经典类:
        没有继承object类,以及该类的子类都是经典类
        只有python2中才存在经典类,因为在python2中没有显示的继承任何类,也不会继承object类

为何要用继承
    减少代码冗余
'''

二、定义基类和子类

class Fclass1:                # 定义父类
    addr = 'shanghai'


class Fclass2:
    commany = 'haymaker'      # 定义分类


class sub2(Fclass1):          # 单继承   基类是Fclass1  派生类或子类是sub2
    name = 'fred'


class sub1(Fclass1, Fclass2):  # 多继承,基类是Fclass1和Fclass2,用逗号隔开
    name = 'Fred'

# 查看继承
print(Fclass1.__bases__)
'''
(<class 'object'>,)    # 基类没有继承任何类,默认继承object类

'''
print(sub1.__bases__)   # __base__是查看所有继承的基类
'''
(<class '__main__.Fclass1'>, <class '__main__.Fclass2'>)
'''
print(object.__dict__)

 三、单继承背景下的属性查找

'''
单继承背景下的属性查找顺序:
    对象————对象的类————父类
'''
class OperationSystem:
    os = 'linux'


class WebService(OperationSystem):
    def __init__(self, name, version):
        self.name = name
        # self.os=OperationSystem.os
        # self.os='ubuntu'
        self.version = version


web = WebService('nginx', '1.2.1')
# web.os = 'windows'            # 在对象中新增os属性
print(web.os)
'''
windows  对象和对象的类中都有os属性,但还是从对象中先查找,即找到os='windows'
'''

'''
ubunto  注释掉web中的os属性,就从对象的类中查找,即在WebService类中找到os='ubuntu'
'''

'''
linux   注释掉WebService类中的os属性,就从父类中查找,即在OperationSystem类中找到os='linux'
'''

四、多继承背景下的属性查找

'''
多继承背景下熟悉查找顺序
    对象————对象的类————按照从左到右一个个分之查找下去
'''

以上多继承的属性查找顺序为:
obj—A—B—E—C—G—D—I
# 第三层
class E:
    # x = 555
    pass


class G:
    # x = 666
    pass


class I:
    x = 777
    pass


# 第二层
class B(E):
    # x = 222
    pass

class C(G):
    # x = 333
    pass


class D(I):
    # x = 444
    pass


# 第一层
class A(B, C, D):
    # x = 111
    pass


obj = A()
# obj.x=0

print(obj.x)
验证结果
菱形继承问题

新式类中会子类会按照MRO调用排在自己下一个的类中的方法,即:

print(A.mro())            # 只有新式类才会有MRO列表

[<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.G'>, <class '__main__.D'>, <class '__main__.I'>, <class '__main__.J'>, <class 'object'>]

# 第四层:
class J:
    x = 888
    pass


# 第三层
class E(J):
    # x = 555
    pass


class G(J):
    # x = 666
    pass


class I(J):
    # x = 777
    pass


# 第二层
class B(E):
    # x = 222
    pass


class C(G):
    # x = 333
    pass


class D(I):
    # x = 444
    pass


# 第一层
class A(B, C, D):
    # x = 111
    pass


obj = A()
# obj.x = 0

print(obj.x)
验证

# coding:utf8


# 第四层:
class J:
    # x = 888
    pass


# 第三层
class E(J):
    # x = 555
    pass


class G(J):
    # x = 666
    pass


class I(J):
    x = 777
    pass


# 第二层
class B(E):
    # x = 222
    pass


class C(G):
    # x = 333
    pass


class D(I):
    # x = 444
    pass


# 第一层
class A(B, C, D):
    # x = 111
    pass


obj = A()
# obj.x = 0

print(obj.x)
验证
'''
新式类:
    属性查找顺序:obj——A——B——E——C——G——D——I——J   广度优先查找,在最后一个分支查找顶级类  根据MRO列表查找
经典类:
    属性查找顺序:ojb——A——B——E——J——C——G——D——I   深度优先查找,在第一个分支就查找顶级类
'''

五、在子类派生出的新方法中重用父类功能的方式(减少代码冗余)

方式1:
'''
指明道姓的访问某一个类的函数

注意:
    1.该方式与继承是没有关系的
    2.访问是某一个类的函数,没有自动传值的效果
'''


class OperationSystem:
    def __init__(self, name, company, version):
        self.name = name
        self.company = company
        self.version = version


class Support(OperationSystem):
    def __init__(self, name, company, version, language):
        OperationSystem.__init__(self,name, company, version)    # 遵守函数传参的个数
        self.language = language


windows=Support('oracle','oracle','12.1','english')

print(windows.__dict__)
'''
{'name': 'oracle', 'company': 'oracle', 'version': '12.1', 'language': 'english'}
'''
方式2
'''
super():只能在子类中用
    Python2:super(自己的类名,对象自己)
    Python3:super()

注意:
    1.该方式严格依赖于继承的mro列表
    2.访问绑定方法,有自动传值的效果
'''


class OperationSystem:
    def __init__(self, name, company, version):
        self.name = name
        self.company = company
        self.version = version


class Support(OperationSystem):
    def __init__(self, name, company, version, language):
        super().__init__(name, company, version)   # OperationSystem.__init__(name,company,version)
        self.language = language


windows = Support('oracle', 'oracle', '12.1', 'english')

print(windows.__dict__)
'''
{'name': 'oracle', 'company': 'oracle', 'version': '12.1', 'language': 'english'}
'''
# coding:utf8

'''
super():只能在子类中用
    Python2:super(自己的类名,对象自己)
    Python3:super()

注意:
    1.该方式严格依赖于继承的mro列表
    2.访问绑定方法,有自动传值的效果
'''


class OperationSystem(object):  # Python2中父类必须手动继承object类 否则会报错super() argument 1 must be type, not classobj
    def __init__(self, name, company, version):
        self.name = name
        self.company = company
        self.version = version


class Support(OperationSystem):
    def __init__(self, name, company, version, language):
        super(Support, self).__init__(name, company, version)  # OperationSystem.__init__(name,company,version)
        self.language = language


windows = Support('oracle', 'oracle', '12.1', 'english')

print(windows.__dict__)
'''
{'name': 'oracle', 'company': 'oracle', 'version': '12.1', 'language': 'english'}
'''
Python2中super()的使用

转载于:https://www.cnblogs.com/lichunke/p/9455188.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值