zoukankan      html  css  js  c++  java
  • Python—面向对象02

    1.抽象类与归一化

    接口,即提供给使用者来调用自己功能的方式、方法、入口

    为什么要使用接口?

    接口提取了一类共同的函数,可以把接口看做一个函数的集合

    然后让子类去实现接口中的函数

    这么做的意义在于归一化,什么叫归一化,就是只要是基于同一个接口实现的类,那么所有的这些类产生的对象在使用时,从用法上来说都一样。

    归一化的好处在于:

    1. 归一化让使用者无需关心对象的类是什么,只需要的知道这些对象都具备某些功能就可以了,这极大地降低了使用者的使用难度。
    2. 归一化使得高层的外部使用者可以不加区分的处理所有接口兼容的对象集合
      1. 就好象linux的泛文件概念一样,所有东西都可以当文件处理,不必关心它是内存、磁盘、网络还是屏幕(当然,对底层设计者,当然也可以区分出“字符设备”和“块设备”,然后做出针对性的设计:细致到什么程度,视需求而定)。
      2. 再比如:我们有一个汽车接口,里面定义了汽车所有的功能,然后由本田汽车的类,奥迪汽车的类,大众汽车的类,他们都实现了汽车接口,这样就好办了,大家只需要学会了怎么开汽车,那么无论是本田,还是奥迪,还是大众我们都会开了,开的时候根本无需关心我开的是哪一类车,操作手法(函数调用)都一样

    模仿interface

    在python中根本就没有一个叫做interface的关键字,如果非要去模仿接口的概念

    可以借助第三方模块:http://pypi.python.org/pypi/zope.interface

    也可以使用继承,其实继承有两种用途

    一:继承基类的方法,并且做出自己的改变或者扩展(代码重用):实践中,继承的这种用途意义并不很大,甚至常常是有害的。因为它使得子类与基类出现强耦合。

    二:声明某个子类兼容于某基类,定义一个接口类(模仿java的Interface),接口类中定义了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口类,并且实现接口中的功能

    class Interface:#定义接口Interface类来模仿接口的概念,python中压根就没有interface关键字来定义一个接口。
        def read(self): #定接口函数read
            pass
    
        def write(self): #定义接口函数write
            pass
    
    
    class Txt(Interface): #文本,具体实现read和write
        def read(self):
            print('文本数据的读取方法')
    
        def write(self):
            print('文本数据的读取方法')
    
    class Sata(Interface): #磁盘,具体实现read和write
        def read(self):
            print('硬盘数据的读取方法')
    
        def write(self):
            print('硬盘数据的读取方法')
    

    上面的代码只是看起来像接口,其实并没有起到接口的作用,子类完全可以不用去实现接口 ,由此引出抽象类

    接下来说 抽象类 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    抽象类

    1 什么是抽象类

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

    2 为什么要有抽象类

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

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

    3 在python中实现抽象类

    import abc
    
    class Animal(metaclass=abc.ABCMeta): #只能被继承,不能被实例化
        all_type='animal'
    
        @abc.abstractmethod
        def run(self):  #定义抽象方法,无需实现功能,且子类必须定义 run 方法
            pass
    
        @abc.abstractmethod
        def eat(self):
            pass
    
    # animal=Animal()  # TypeError: Can't instantiate abstract class Animal with abstract methods eat, run
    
    
    class People(Animal):
        def run(self):
            print('people is running')
    
        def eat(self):
            print('people is eating')
    
    class Pig(Animal):
        def run(self):
            print('pig is walking')
    
        def eat(self):
            print('pig is eating')
    
    class Dog(Animal):
        pass
    
    # dog1 = Dog()  # 报错 ,TypeError: Can't instantiate abstract class Dog with abstract methods eat, run 
    # 没有实现抽象类里面的方法
    
    peo1=People()
    pig1=Pig()
    
    peo1.run()  # people is running
    pig1.run()  # pig is walking
    
    print(peo1.all_type)  # animal
    print(pig1.all_type)  # animal
    

    关于接口与抽象类:

    抽象类的本质,还是类。指的是一组类的相似性,包括数据属性和函数属性。

    而接口只强调函数属性的相似性。

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

    2. 多态与多态性

    多态

    多态指的是一类事物有多种形态,比如,动物有多种形态:人,狗,猪

    水有多种形态:气、液、固

    多态性是指在不考虑实例类型的情况下使用实例,多态性分为静态多态性和动态多态性

    静态多态性:如任何类型都可以用运算符+进行运算。。。。。如,str + str ,list + list, num + num

    动态多态性:看如下代码

    #多态:同一类事物的多种形态
    import abc
    class Animal(metaclass=abc.ABCMeta): #同一类事物:动物
        @abc.abstractmethod
        def talk(self):
            pass
    
    class People(Animal): #动物的形态之一:人
        def talk(self):
            print('say hello')
    
    class Dog(Animal): #动物的形态之二:狗
        def talk(self):
            print('say wangwang')
    
    class Pig(Animal): #动物的形态之三:猪
        def talk(self):
            print('say aoao')
    
    class Cat(Animal):
        def talk(self):
            print('say miamiao')
    
    #多态性:指的是可以在不考虑对象的类型的情况下而直接使用对象
    peo1=People()
    dog1=Dog()
    pig1=Pig()
    cat1=Cat()
    
    # peo、dog、pig都是动物,只要是动物肯定有talk方法
    # 于是我们可以不用考虑它们三者的具体是什么类型,而直接使用
    
    peo1.talk()  # say hello
    dog1.talk()  # say wangwang
    pig1.talk()  # say aoao
    
    #更进一步,我们可以定义一个统一的接口来使用
    def func(obj):   # 对于使用者来说,自己的代码根本无需改动
        obj.talk()
    
    cat1 = Cat()
    func(cat1)  # say miamiao
    # 甚至连调用方式也无需改变,就能调用猫的talk功能
    # 这样我们新增了一个形态Cat,由Cat类产生的实例cat1,使用者可以在完全不需要修改自己代码的情况下。使用和人、狗、猪一样的方式调用cat1的talk方法,即func(cat1)
    

    多态性的好处:

    灵活性:以不变应万变,不论对象千变万化,使用者都是同一种形式去调用,如func(animal)

    可扩展性:通过继承animal类创建了一个新的类,使用者无需更改自己的代码,还是用func(animal)去调用   

    3.鸭子类型

    Python崇尚鸭子类型,即‘如果看起来像、叫声像而且走起路来像鸭子,那么它就是鸭子’

    python程序员通常根据这种行为来编写程序。例如,如果想编写现有对象的自定义版本,可以继承该对象

    也可以创建一个外观和行为像,但与它无任何关系的全新对象,后者通常用于保存程序组件的松耦合度。

    例1:利用标准库中定义的各种‘与文件类似’的对象,尽管这些对象的工作方式像文件,但他们没有继承内置文件对象的方法

    #二者都像鸭子,二者看起来都像文件,因而就可以当文件一样去用
    class TxtFile:
        def read(self):
            pass
    
        def write(self):
            pass
    
    class DiskFile:
        def read(self):
            pass
        def write(self):
            pass
    

    例2:序列类型有多种形态:字符串,列表,元组,但他们之间没有直接的继承关系

    #str,list,tuple都是序列类型
    s=str('hello')
    l=list([1,2,3])
    t=tuple((4,5,6))
    
    #我们可以在不考虑三者类型的前提下使用s,l,t
    s.__len__()
    l.__len__()
    t.__len__()
    
    len(s)
    len(l)
    len(t)
    

  • 相关阅读:
    qs.stringify() 和JSON.stringify()的区别 飞鸟和蝉
    js随机数, 范围随机数 飞鸟和蝉
    VUECLI 4的跨域解决方案
    vue3elementadmin
    English dedicate 致力 题献
    解决java web项目导入后出现的问题 cannot be read or is not a valid ZIP file
    SQL 优化原则(转)
    Java Spring Error : Bean property '*****' is not writable or has an invalid setter method.
    c++面试题:#define MIN(A,B) ( (A) <= (B) ? (A) : (B) )
    freemark list 循环变量类型错误问题
  • 原文地址:https://www.cnblogs.com/friday69/p/9359465.html
Copyright © 2011-2022 走看看