zoukankan      html  css  js  c++  java
  • 继承,多态

    #继承:模糊到具体
    #抽象:具体到模糊
    #先抽象后继承
    # 继承有几种:单继承,多继承
    # 猫类 抓老鼠
    # 狗类 看门
    # 动物 吃 喝 睡
    # class Animal:
    # def eat(self):
    # print('eating')
    # def drink(self):
    # print('drinking')
    # def sleep(self):
    # print('sleeping')
    # class Cat(Animal):
    # def catch_mouse(self):
    # print('yeah')
    # class Dog(Animal):
    # def watch_door(self):
    # print('wangwang')
    # kitty = Cat()
    # kitty.eat()
    # snoopy = Dog()
    # snoopy.eat()

    抽象类

    什么是抽象类

        与java一样,python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化

    为什么要有抽象类

        如果说类是从一堆对象中抽取相同的内容而来的,那么抽象类是从一堆中抽取相同的内容而来的,内容包括数据属性和函数属性。

      比如我们有香蕉的类,有苹果的类,有桃子的类,从这些类抽取相同的内容就是水果这个抽象的类,你吃水果时,要么是吃一个具体的香蕉,要么是吃一个具体的桃子。。。。。。你永远无法吃到一个叫做水果的东西。

        从设计角度去看,如果类是从现实对象抽象而来的,那么抽象类就是基于类抽象而来的。

      从实现角度来看,抽象类与普通类的不同之处在于:抽象类中有抽象方法,该类不能被实例化,只能被继承,且子类必须实现抽象方法。这一点与接口有点类似,但其实是不同的,即将揭晓答案

    在python中实现抽象类

     View Code

    抽象类与接口类

    抽象类的本质还是类,指的是一组类的相似性,包括数据属性(如all_type)和函数属性(如read、write),而接口只强调函数属性的相似性。

    抽象类是一个介于类和接口直接的一个概念,同时具备类和接口的部分特性,可以用来实现归一化设计 

    在python中,并没有接口类这种东西,即便不通过专门的模块定义接口,我们也应该有一些基本的概念。

    1.多继承问题

    在继承抽象类的过程中,我们应该尽量避免多继承;
    而在继承接口的时候,我们反而鼓励你来多继承接口

    接口隔离原则:
    使用多个专门的接口,而不使用单一的总接口。即客户端不应该依赖那些不需要的接口。

    2.方法的实现

    在抽象类中,我们可以对一些抽象方法做出基础实现;
    而在接口类中,任何方法都只是一种规范,具体的功能需要子类实现

    钻石继承

    继承顺序

     继承顺序

    继承原理

    python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表,例如

    >>> F.mro() #等同于F.__mro__
    [<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]

    为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。
    而这个MRO列表的构造是通过一个C3线性化算法来实现的。我们不去深究这个算法的数学原理,它实际上就是合并所有父类的MRO列表并遵循如下三条准则:
    1.子类会先于父类被检查
    2.多个父类会根据它们在列表中的顺序被检查
    3.如果对下一个类存在两个合法的选择,选择第一个父类

    继承小结

    继承的作用

    减少代码的重用
    提高代码可读性
    规范编程模式

    几个名词

    抽象:抽象即抽取类似或者说比较像的部分。是一个从具题到抽象的过程。
    继承:子类继承了父类的方法和属性
    派生:子类在父类方法和属性的基础上产生了新的方法和属性

    # 人类 狗类 相同的属性 提取了一个__init__方法,在这个方法里放一些共有的属性
    # 猫类和狗类 相同的方法 直接把相同的方法提取出来,放在基类里

    # 他大舅他二舅都是他舅 —— 实例化
    # 高桌子低板凳都是木头 —— 继承

    # 人 狗 相同属性的同时 还有一些不同的属性
    # class Animal:
    # def __init__(self, name,aggressivity, life_value):
    # self.name = name # 每一只狗都有自己的昵称;
    # self.aggressivity = aggressivity # 每一只狗都有自己的攻击力;
    # self.life_value = life_value # 每一只狗都有自己的生命值;
    # def eat(self):
    # self.life_value += 10
    # class Dog(Animal): # 定义一个狗类
    # def __init__(self, name, breed, aggressivity, life_value):
    # # Animal.__init__(self,name,aggressivity, life_value)
    # super(Dog, self).__init__(name,aggressivity, life_value)
    # self.breed = breed # 每一只狗都有自己的品种;
    #
    # def bite(self, people):
    # people.life_value -= self.aggressivity
    # # 人
    # class Person(Animal): # 定义一个人类
    # def __init__(self, name, aggressivity, life_value, money):
    # # Animal.__init__(self,name, aggressivity, life_value)
    # super().__init__(name, aggressivity, life_value)
    # self.money = money#派生属性:父类没有的属性
    # def attack(self, dog):
    # dog.life_value -= self.aggressivity
    #
    # def eat(self):
    # Animal.eat(self)
    # super().eat()
    # print('dog is eating')
    # # snoopy = Dog('点点','大黑',20,250)
    # ren = Person('哲',10,100,100)
    # ren.attack(snoopy)
    # print(snoopy.life_value)

    # print(snoopy.breed)
    # print(snoopy.name)
    # snoopy.eat()
    # print(snoopy.life_value)
    # super(Dog,snoopy).eat()
    # print(snoopy.life_value)

    # 用子类的对象,调用父类的方法
    #如果子类中没有这个方法,直接就使用父类的
    # 如果子类中有同名方法:
    #经典类 指名道姓 类名 (子类对象) 类内外一致
    # 新式类 super方法 super(子类名,子类对象),方法名() 类内可以省略的super的参数


    # class Foo:
    # def __init__(self):
    # self.func()
    # def func(self):
    # print('Foo.func')
    # class Son(Foo):
    # def func(self):
    # print('son.func')
    # s = Son()
    # d = Foo()

    # 钻石继承问题
    # 经典类和新式类的多继承问题,继承顺序问题
    # 经典类:博大精深 所以经典类就是深度优先
    # 新式类:广度优先
    # class F(object):
    # pass
    # def f(self):
    # print('f')
    # class E(F):
    # pass
    # def f(self):
    # print('E')
    #
    # class D(F):
    # pass
    # def f(self):
    # print('D')
    #
    # class B(D):
    # pass
    # def f(self):
    # print('B')
    #
    # class C(E):
    # pass
    # def f(self):
    # print('C')
    #
    # class A(B, C):
    # pass
    # def f(self):
    # print('A')
    # a = A()
    # a.f()
    # print(A.mro())新式类

    # 多态
    # 多态指的是一类事物有多种形态
    #
    # 动物有多种形态:人,狗,猪
    # 鸭子类型
    #
    # 逗比时刻:
    #
    #   Python崇尚鸭子类型,即‘如果看起来像、叫声像而且走起路来像鸭子,那么它就是鸭子’
    #
    # python程序员通常根据这种行为来编写程序。例如,如果想编写现有对象的自定义版本,可以继承该对象
    #
    # 也可以创建一个外观和行为像,但与它无任何关系的全新对象,后者通常用于保存程序组件的松耦合度。
    #
    # 例1:利用标准库中定义的各种‘与文件类似’的对象,尽管这些对象的工作方式像文件,但他们没有继承内置文件对象的方法
    #
    # 例2:序列类型有多种形态:字符串,列表,元组,但他们直接没有直接的继承关系
    class Animal:pass
    class Person(Animal):
    def attack(self):
    pass
    class Dog(Animal):
    def attack(self):
    pass
    def attack(obj):
    obj.attack()
    d = Dog()
  • 相关阅读:
    在tomcat集群下利用redis实现单点登陆
    redis的入门篇---五种数据类型及基本操作
    redis的入门篇----启动和关闭
    window下nginx负载均衡简单配置-----权重的实现
    nginx的负载均衡配置,常用策略
    修改tomcat启动窗口的名称
    windows单机环境下配置tomcat集群
    maven的隔离部署
    什么是cap
    spring整合redis-----ShardedJedisPool实现
  • 原文地址:https://www.cnblogs.com/zhuchuanbo/p/7874077.html
Copyright © 2011-2022 走看看