day-25面向对象

继承的另一种使用方式

最常见的是直接继承一个已经存在的类

当你想要创建一个新的类 发现这个类中的一些 在某一个类中已经存在

那就没有必要从头开始写 ,可以直接继承已有的类 然后做补充

注意:当你覆盖了init方法时
  不要忘记调用super().init函数让父类完成原有的初始化操作

class MyList(list):
    def __init__(self,element_cls):
        # 当你覆盖了init方法时
        # 不要忘记调用super().init函数让父类完成原有的初始化操作
        super().__init__()
        self.element_cls = element_cls

        
    def append(self, object):
        # if isinstance(object,str)
        if object.__class__ == self.element_cls:
            super().append(object)
        else:
            print("只能存储%s类型!" % self.element_cls.__name__)

多继承的问题

python支持多继承 一个类可以同时继承多个父类

好处:是更加灵活

问题:多继承时如果多个父类中出现了同名的属性/函数,属性的查找顺序该怎么确定

办法:需要使用mro列表来查看真正的继承顺序

最后:尽量不要使用多继承

class A:
    def test(self):
        print("from A")
        super().test() # 应该报错..... 但是却执行成功了
class B:
    def test(self):
        print("from B")
    pass

class C(A,B):
    pass

c = C()
c.test()

组合

指的是 一个类把另一个类的对象作为自己的属性 就称之为组合

都是用用来重用代码的方式:
组合描述的是  什么拥有什么的关系     学生 有 书 学生有手机
基础描述的是  什么是什么的关系     麦兜是猪 猪猪侠也是猪

class PC:
    def open_app(self,app_name):
        print("open %s" % app_name)

class OldBoyStudent:
    def __init__(self,PC,notebook):
        self.PC = PC
        self.notebook = notebook
    pass

pc = PC()
notebook = PC()


stu = OldBoyStudent(pc,notebook)

菱形继承问题

新式类与经典类

经典类:不是object的子类 仅在py2中出现

  深度优先

新式类:object的子类 py3中都是新式类

  先深度 直到有一个公共父类时,查找其他路线(基于C3算法)

注意:经典类没有mro列表

py2中 A就是一个经典类

class A:
   pass


如果你的代码需要兼容py2 那应该显式的继承object 无论是直接还是间接继承

class B(object):
    pass

class A(B):
    pass

新式类的顺序
 E B C D A object
经典类的顺序
 E B A C D

class A:
    # a = 1
    pass

class B(A):
    # a = 2
    pass

class C(A):
    # a = 3
    pass

class D(A):
    # a = 4
    pass

class E(B,C,D):
    # a = 5
    pass

e1 = E()
print(E.mro())

 

 

接口

接口:是一套协议规范

  有一堆函数   但是只明确了函数的名称 没有明确函数具体实现

好处:使用接口可以提高程序的扩展性

class USB:

    def open(self):
        pass

    def close(self):
        pass

    def work(self):
        pass

抽象类

具备抽象方法的类
  抽象方法是 没有函数体的方法

特点:不能直接实例化,必须有子类覆盖了所有抽象方法后才能实例化子类
   既可以有抽象方法也可以有普通方法
方法:通过abc模块来实现
  用@abc.abstractmethod 装饰器
意义:通过抽象类来强行限制子类必须覆盖所有的抽象方法
  
import abc

class Test(metaclass=abc.ABCMeta):

    @abc.abstractmethod
    def say_hi(self):
        pass

class TT(Test):

    def say_hi(self):
        print("i am TT obj")

t = TT()
t.say_hi()

抽象类与接口区别

接口是指只有方法声明而没有实现体 , 接口中所有方法都是抽象的

抽象类既可用后抽象方法也可以有普通方法

接口的出现是为了提高扩展性,抽象类是为类限制子类必须按照父类要求的来实现

鸭子类型

对于一个优秀的程序员,即时没有接口和抽象类的限制,也能写出一个具备扩展性的程序

鸭子类型:这个对象 长的想鸭子 叫声像鸭子 走路像鸭子 那它就是鸭子

    就可以把它当成鸭子来使用

class PC():

    def conntent_device(self, usb_device):
        usb_device.open()
        usb_device.work()
        usb_device.close()

class Mouse:
    # 实现接口规定的所有功能
    def open(self):
        print("mouse opened")

    def work(self):
        print("mouse working...")

    def close(self):
        print("mouse closed")

mouse = Mouse()
pc = PC()

pc.conntent_device(mouse)



class KeyBoard:
    def open(self):
        print("KeyBoard opened")

    def work(self):
        print("KeyBoard working...")

    def close(self):
        print("KeyBoard closed")

key1 = KeyBoard()

# 如果key1的特征和行为都像USB设备 那就把它当做USB设备来使用
# 对于使用者而言可以不用关心这个对象是什么类,是如如何是实现,
pc.conntent_device(key1)

猜你喜欢

转载自www.cnblogs.com/klw1/p/10883193.html