zoukankan      html  css  js  c++  java
  • 组合||抽象类||多态||鸭子类型

    组合

    软件重用的重要方式除了继承之外还有另外一种方式,即:组合

    组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合

    class People:
        def __init__(self,name,age,sex):
            self.name = name
            self.age  = age
            self.sex  = sex
    
    class Renwen(People):
        def __init__(self,name,age,sex,weapon):
            super().__init__(name,age,sex)
            self.weapon = weapon
            self.attribute = [] #锐雯的属性列表
        def skill(self):
            print('%s is skill'%self.name)
    
    class Teacher(People):
        def __init__(self,name,age,sex,level):
            super().__init__(name,age,sex)
            self.level = level
    
        def teach(self):
            print("%s is teaching" %self.name)
    
    class Attribute:
        def __init__(self,damage,spell,armor):
            self.danage = damage
            self.spell = spell
            self.armor =armor
    
        def tell_info(self):
            print("生命值:%s,法术:%s,护甲:%s"%(self.danage,self.spell,self.armor))
    
    rewen = Renwen('锐雯',22,'female',"砍刀")
    teacher1 =Teacher('林书行',30,'male',20)
    
    a = Attribute(200,20,100)#创建属性对象
    
    rewen.attribute.append(a) #添加属性值
    
    #打印出属性值
    for i in rewen.attribute:
        i.tell_info()
    View Code

     抽象类

    • 如果说类是从一堆对象中抽取相同的内容而来的,那么抽象类就是从一堆类中抽取相同的内容而来的,内容包括数据属性和函数属性。
    • 比如我们有香蕉的类,有苹果的类,有桃子的类,从这些类抽取相同的内容就是水果这个抽象的类,你吃水果时,要么是吃一个具体的香蕉,要么是吃一个具体的桃子。你永远无法吃到一个叫做水果的东西。
    • 从设计角度去看,如果类是从现实对象抽象而来的,那么抽象类就是基于类抽象而来的。
    • 从实现角度来看,抽象类与普通类的不同之处在于:抽象类中只能有抽象方法(没有实现功能),该类不能被实例化,只能被继承,且子类必须实现抽象方法。这一点与接口有点类似,但其实是不同的,即将揭晓答案
    #一切皆文件
    import abc #利用abc模块实现抽象类
    
    class All_file(metaclass=abc.ABCMeta):
        all_type='file'
        @abc.abstractmethod #定义抽象方法,无需实现功能
        def read(self):
            '子类必须定义读功能'
            pass
    
        @abc.abstractmethod #定义抽象方法,无需实现功能
        def write(self):
            '子类必须定义写功能'
            pass
    
    # class Txt(All_file):
    #     pass
    #
    # t1=Txt() #报错,子类没有定义抽象方法
    
    class Txt(All_file): #子类继承抽象类,但是必须定义read和write方法
        def read(self):
            print('文本数据的读取方法')
    
        def write(self):
            print('文本数据的读取方法')
    
    class Sata(All_file): #子类继承抽象类,但是必须定义read和write方法
        def read(self):
            print('硬盘数据的读取方法')
    
        def write(self):
            print('硬盘数据的读取方法')
    
    class Process(All_file): #子类继承抽象类,但是必须定义read和write方法
        def read(self):
            print('进程数据的读取方法')
    
        def write(self):
            print('进程数据的读取方法')
    
    wenbenwenjian=Txt()
    
    yingpanwenjian=Sata()
    
    jinchengwenjian=Process()
    
    #这样大家都是被归一化了,也就是一切皆文件的思想
    wenbenwenjian.read()
    yingpanwenjian.write()
    jinchengwenjian.read()
    
    print(wenbenwenjian.all_type)
    print(yingpanwenjian.all_type)
    print(jinchengwenjian.all_type)
    View Code

    多态

    多态是指同一事物拥有多种形态

    例如:

    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 miaomiao')
    View Code

    多态性

    多态性是指在不考虑实例类型的情况下使用实例,多态性分为静态多态性和动态多态性
    静态多态性:如任何类型都可以用运算符+进行运算
    动态多态性:如下

    peo=People()
    dog=Dog()
    pig=Pig()
    
    #peo、dog、pig都是动物,只要是动物肯定有talk方法
    #于是我们可以不用考虑它们三者的具体是什么类型,而直接使用
    peo.talk()
    dog.talk()
    pig.talk()
    
    #更进一步,我们可以定义一个统一的接口来使用
    def func(obj):
        obj.talk()
    View Code

    多态性的好处

    1.增加了程序的灵活性

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

    2.增加了程序额可扩展性

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

    class Cat(Animal): #属于动物的另外一种形态:猫
            def talk(self):
               print('say miao')
    
    def func(animal): #对于使用者来说,自己的代码根本无需改动
            animal.talk()
    
    cat1=Cat() #实例出一只猫
    func(cat1) #甚至连调用方式也无需改变,就能调用猫的talk功能
    say miao
    View Code

    这样新增了一个形态Cat,由Cat类产生的实例cat1,使用者可以在完全不需要修改自己代码的情况下。使用和人、狗、猪一样的方式调用cat1的talk方法,即func(cat1)

    鸭子类型

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

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

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

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

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

    例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)
    View Code
  • 相关阅读:
    FlatBuffers要点
    tarjan+缩点+强连通定理
    编程之美2.16 最长递增子序列
    Android Studio之多个Activity的滑动切换(二)
    Effective java读书札记第一条之 考虑用静态工厂方法取代构造器
    【PM】关于系统数据库和服务现场升级的一些看法
    用户及权限基础 2---- 权限
    Android双向滑动菜单完全解析,教你如何一分钟实现双向滑动特效
    【转贴】gdb中的信号(signal)相关调试技巧
    基于新浪sae使用php生成图片发布图文微博
  • 原文地址:https://www.cnblogs.com/Mryang123/p/8597973.html
Copyright © 2011-2022 走看看