数据结构( Pyhon 语言描述 ) — — 第6章:继承和抽象类

      • 继承
        • 新的类通过继承可以获得已有类的所有特性和行为
          • 继承允许两个类(子类和超类)之间共享数据和方法
          • 可以复用已有的代码,从而消除冗余性
          • 使得软件系统的维护和验证变得简单
          • 子类通过修改自己的方法或者添加新的方法,从而将超类的行为特殊化
          • 子类可以调用超类的方法,需要使用超类的名称作为该方法的前缀
      • 使用继承定制一个已有的类
        • 已有类的子类化
          • 子类和超类(父类)的继承关系
            • clip_image001[4]
            • 由于 ArrayBag 类实现了 BagInterface,所以 ArraySortedBag 也通过继承实现了这个接口
          • 创建已有类的一个子类的步骤
            • 为了保证能够实现继承,必须将父类名称放在类声明头部的圆括号中
            • 修改必须修改的方法的代码(包括 __init__ 方法
            • 添加新的方法
        • __init__ 方法
          • 在子类中调用父类的方法
            • <parent class name>.<method name>( self, <other arguments> )
            • 示例
              • """

                File: arraysortedbag.py

                 

                """

                from arraybag import ArrayBag

                 

                class ArraySortedBag( ArrayBag ):

                    """An array-based sorted bag implementation."""

                   

                    #Constructor

                    def __init__( self, sourceCollection = None ):

                        """Sets the initial state of self, which includes the contents

                        of sourceCollection, if it's present."""

                        ArrayBag.__init__( self, sourceCollection )

        • 添加新的 contains 方法
          • 在有序包上执行二叉搜索
            • #!/usr/bin/env python

              # -*- coding:utf-8 -*-

              # Author:Lijunjie

               

              """

              File: arraysortedbag.py

               

              """

              from arraybag import ArrayBag

               

              class ArraySortedBag( ArrayBag ):

                  """An array-based sorted bag implementation."""

                 

                  #Constructor

                  def __init__( self, sourceCollection = None ):

                      """Sets the initial state of self, which includes the contents

                      of sourceCollection, if it's present."""

                      ArrayBag.__init__( self, sourceCollection )

                     

                     

                  #Accessor method

                  def __contains__( self, item ):

                      """Return True if item is in self, or False otherwise"""

                      left = 0

                      right = len( self ) - 1

                      while left <= right:

                          midpoint = ( left + right ) // 2

                          if self._items[midpoint] == item :

                              return True

                          if self._items[midpoint] > item :

                              right = midpoint - 1

                          else:

                              left = midpoint + 1

                      return False 

        • 修改已有的 add 方法
          • 代码
            •     #Mutator method

                  def add( self, item ):

                      """Adds item to self."""

                      #Empty or last item, call ArrayBag.add

                      if self.isEmpty() or item >= self._items[len( self ) - 1]:

                          ArrayBag.add( self, item )

                      else:

                          #Resize the array if it is full here

                          #Search for the first item > = new item

                          targetIndex = 0

                          while item > self._items[targetIndex]:

                              targetIndex += 1

                          #open a hole for a newitem

                          for index in range( len( self ), targetIndex, -1 ):

                              self._items[index] = self._items[index - 1]

                          #insert item and update size

                          self._items[targetIndex] = item

                          self._size += 1 

        • ArraySortedBag的运行时间性能
          • ArraySortedBag__contains__方法的时间复杂度从 降为(logn),从而优化了其它借助于 __contains__方法的方法,即 in 运算符。比如 __eq__ 方法。clip_image002[4]
        • Python中的类层级
          • Python 所有的内建的类都位于一个层级中,这个层级的最项端或根部的是 object 类。
          • Python支持对多个父类的子类化和继承
      • 使用抽象类去除代码的冗余性
        • 抽象类
          • 抽象类是一种超类
          • 它捕获了相关一组类的通用特征和行为,从而可以去除已知类中冗余的方法和数据
          • 抽象类不能正常的实例化,它的子类叫做具体类
        • 设计一个 AbstractBag
          • 冗余的方法
            • 最显而易见的冗余的方法是直接调用其他方法,并且没有直接访问实例变量的那些方法
          • 冗余的变量
            • 要找出冗余,必须查看该变量引用的是何种数据类型
          • 抽象类的框架
            • clip_image003[4]
            • AbstractBag 类并没有实现包接口
            • 通常,一个类的方法和变量对其所有子孙类都是通用的
        • 重写 AbstractBag 中的 __init__ 方法
          • 代码
            • """

              File: abstractbag.py

              Author: Lijunjie

              """

               

               

              class AbstractBag( object ):

                  """An abstract bag implementation."""

                 

                  #Constructor

                  def __init__( self, sourceCollection = None ):

                      """Sets the initial state of self, which includes the contents

                      of sourceCollection, if it's present."""

                      self._size = 0

                      if sourceCollection:

                          for item in sourceCollection:

                              self.add( item ) 

        • 修改 AbstractBag 的子类
          • """

            File: arraybag.py

            Author: Lijunjie

            """

             

            from arrays import Array

            from abstractbag import AbstractBag

             

            class ArrayBag( AbstractBag ):

                """An array-based bag implementation."""

               

                #Class variable

                DEFAULT_CAPACTIY = 10

               

                #Constructor

                def __init__( self, sourceCollection = None ):

                    """Sets the initial state of self, which includes the contents

                    of sourceCollection, if it's present."""

                    self._items = Array( ArrayBag.DEFAULT_CAPACTIY )

                    AbstractBag.__init__( self, sourceCollection ) 

        • AbstractBag 中的 __add__ 方法泛化
          • 使用 type 函数来获取 self 的类型
          • 代码
            •     def __add__( self, other ):

                      """Return a new bag containing the contents of self and other"""

                      result = type( self )( self )

                      for item in other:

                          result.add( item )

                      return result 

      • 所有集合的一个抽象类
        • 开发适用于整个集合层级的基础类
        • AbstractCollection 整合到集合层级中
          • 最通用的方法: isEmpty __len__ __add__。表示它们的实现不需要由子类来修改
          • AbstrcatCollection 中还可以定义 __str__ __eq__ 的默认实现
          • 集合框架
            • clip_image004[4]
            • 层级从上到下,类在特征上从较为通用倾向于更为具体
        • __eq__方法中使用两个迭代类
          • next 函数
            • 当在一个迭代器对象上调用 next 函数时,其会返回迭代器序列中的当前项,并且会前进一步到下一项。如果没有当前项,会抛出 StopIteration 异常
          • __eq__方法代码
            •     def __eq__( self, other ):

                      """Return True if self equals other, otherwise False."""

                      if self is other: return True

                      if type( self ) != type( other ) or len( self ) != len( other ):

                          return False

                      otherIter = iter( other )

                      for item in self:

                          if item != next( otherIter ):

                              return False

                      return True 

 

posted @ 2018-11-01 21:09  木子识时务  阅读(238)  评论(0编辑  收藏  举报