zoukankan      html  css  js  c++  java
  • 面向对象之继承,组合

    一:继承基础

    【1】基础概念

    (1)继承

      (1)定义:是一种定义新类的方式

      (2)继承类被称之为子类/派生类 被继承者被称为父类/基类

      例如:王思聪继承王健林的财产 那么王思聪就是属于子类 而王健林属于父类

    PS:在程序中继承属于 类与类之间的关系

    (2)作用:

      (1)子类可以继承父类中的某些属性,方法等

      (2)子类可以重复使用父类的代码 提高代码的使用量

    (3)使用方式:

      (1)语法:class +类名(父类名称):

    例如:

    class Father:
        pass
    
    
    class Son(Father):
        pass
    
    
    print(Son.__bases__) # (<class '__main__.Father'>,)

    【2】继承扩展:

    (1)抽象:

      (1)继承描述的是一种什么是什么的关系 在继承之前必须先抽象

      (2)抽象是将多个子类具有相同属性和特征抽取出来 形成一个新的类 

      (3)继承一个已经现存的类 可以修改或者扩展原有功能

    案例展示:

    class Father:
    
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
    
    class Son(Father):
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
    fat = Father('爸爸',40)
    
    son = Son('儿子',18)
    
    print(fat.name) # 爸爸
    print(son.name) # 儿子
    
    # PS:可以看见其中有很多重复代码
    抽象产生原因案例

    PS:其中有大量的重复的代码 代码组织架构比较差

    解决方法:

    class Person:
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
    
    class Father(Person):
        print('从上述父类调用')
    
    
    
    class Son(Person):
        print('从上述父类调用')
    
    
    
    fat = Father('爸爸',40)
    
    son = Son('儿子',18)
    
    print(fat.name) # 爸爸
    print(son.name) # 儿子
    抽象好处

    PS:其通过抽取大量相同的特征 汇总成一个新类 其余类继承这个新类 减少代码的冗余

    (2)属性的查找顺序:

      (1)首先查找对象本身

      (2)查找对象所属的类

      (3)查找父类

      (4)查找object

    例如:

    class Person:
        # 类被注释
        test = '父类'
    
    
    
    class Father(Person):
    
        # 对象被注释
        test = ''
        pass
    
    
    fat = Father()
    fat.test = '对象'
    print(fat.test)  
    '''
    1:对象
    2:类
    3:父类
    
    '''
    属性查找顺序

    (3)派生:

        (1)当一个子类出现于父类中不同的内容时候

        (2)通常子类都会出现于父类不同的内容 如果完全相同也没什么意义 

        (3)其主要是为了在继承父类属性和方法之上 扩展自己的功能

    例如:

    class Animal:
        def run(self):
            print('动物都喜欢跑')
    
    
    
    
    class Cat(Animal):
    
        # 扩展的新的函数 功能
        def eat(self):
            print('猫喜欢吃鱼')
    
    
    cat = Cat()
    
    # 继承父类的行为
    cat.run() # 动物都喜欢跑
    
    # 调用新的属性
    cat.eat() # 猫喜欢吃鱼
    
    #  添加自己新的属性
    cat.color = '黑猫警长'
    print(cat.color) # 猫喜欢吃鱼
    派生案例

    (4)覆盖

      (1)也称之为重写

      (2)子类出现了与父类一样的东西

      (3)当对象在调用的时候会以子类的为准

    例如:

    class Animal:
        def run(self):
            print('动物都喜欢跑')
    
    
    
    
    class Cat(Animal):
        def run(self):
            print('动物Cat都喜欢跑')
    
        # 扩展的新的函数 功能
        def eat(self):
            print('猫喜欢吃鱼')
    
    
    cat = Cat()
    
    # 继承父类的行为
    cat.run() # 动物Cat都喜欢跑 直接查找类属性
    覆盖案例

    (4)子类调用父类的方式:

      (1)继承:即子类与父类关联比较相近的时候

      (2)super:子类与父类关联不是那么相近

      (3)指名道姓 父类名.父类方法 子类与父类关联不是那么相近

    案例展示:

    (1)super:

    class Phone:
        def call(self,name):
            print('%s使用手机打电话'%name)
    
    class Person(Phone):
        def run(self):
            super().call('SR')
    
    
    per = Person()
    per.run() # SR使用手机打电话

    (2)指名道姓:

    class Phone:
        def call(self,name):
            print('%s使用手机打电话'%name)
    
    class Person(Phone):
        def run(self):
            Phone.call(self,'SR')
    
    
    per = Person()
    per.run() # SR使用手机打电话

    PS:其跟继承没什么关系

     练习:如何限制一个元素类型存入空间中

    例如:

    # 可以直接调用list作为存储
    class My_list(list):
    
        # 初始化定义类型
        def __init__(self,element_type):
            self.element = element_type
    
        def append(self, object):
            # 判断初始化类型 是否为自己要加入的 如果是则加入
            if type(object) == self.element:
                super().append(object)
            else:
                print('错误的类型')
    
    
    # 调用列表作为存储空间
    class My_list(list):
        # 定义初始化要加入的元素类型
        def __init__(self,element_type):
            self.element_type = element_type
    
        # 定义要添加的函数
        def append(self, object):
            # 判断加入的类型 是否为自己想要加入的类型
            if type(object) == self.element_type:
                super().append(object)
            else:
                print('类型错误')
    
    # 初始化传入类型
    m = My_list(int)
    m.append(1)
    print(m[0]) # 1
    
    # 报错 其不是整形
    m.append('123')
    print(m[1]) # 类型错误
    限制元素加入

     

    二:组合

    【1】:基础概念

    (1)概念

      (1)也是一种关系 描述是什么有什么的关系

      (2)在python中将一个对象做为令一个对象的属性

    (2)组合目的:

      (1)也是复用代码

      (2)耦合度降低 减少代码之间的影响

    class Phone:
        def __init__(self,kind,price,):
            self.kind = kind
            self.price = price
    
        def call(self):
            print('正在通话中')
    
    class Student:
        def __init__(self,name,phone):
    
            self.name = name
            self.phone = phone
    
            print('%s正在使用手机通话'%self.name)
    
    pho = Phone('Apple',9999)
    
    stu = Student('SR',pho)
    
    stu.phone.call() # 正在通话中
    组合

    PS:

    (1)Student想调用Phone需要将其存入自己的名称空间中

    (2)当将其存入自己的名称空间时候 需要保持对象与名称空间一致 于是对象也需要传参

    (3)创建对象就是实例化的过程 可以将另外一个类所对应的变量pho以参数的形式上传给类内部的函数中

    (4)函数会收到该参数 然后与其交互数据

    (3)菱形继承

      (1)新式类:

        (1)其显示或者隐式属于object的子类

        (2)在python3中全部都是新式类

      (2)经典类

        (1)不属于object的子类   

        (3)其只在python2中才会出现

    (4)菱形查找顺序

      (1)经典类:

        在python2中多继承情况下 在要查找的属性不存在的时候 会执行深度查找

    图解:

     (3)新式类:

      (1)在python3中如果没有共同的父类 其会执行深度优先

      (2)如果其拥有共同的父类其会执行广度优先

    PS:

    (1)可以通过mro查看查找顺序

    (2)在python2中没有这个参数

  • 相关阅读:
    传球游戏(NOIP2008 普及组第三题)
    立体图(NOIP2008 普及组第四题)
    多项式输出(NOIP2009 普及组第一题)
    分数线划定(NOIP2009 普及组第二题)
    第5到8章
    第四章总结
    实验九
    实验五
    实验四
    实验三
  • 原文地址:https://www.cnblogs.com/SR-Program/p/11247558.html
Copyright © 2011-2022 走看看