zoukankan      html  css  js  c++  java
  • Python面向对象三要素-多态

                 Python面向对象3要素-多态

                                     作者:尹正杰

    版权声明:原创作品,谢绝转载!否则将追究法律责任。

     一.多态概述

      OCP原则:多用“继承”,少修改。
    
      继承的用途:在子类上实现对基类的增强,实现多态。

      在面向对象这种,父类,子类通过继承联系在一起,如果可以通过一套方法,就可以实现不同表现,就是多态。

      一个类继承自多个类就是多继承,它将具有多个类的特征。

      

    二.多态案例

      我们之前已经学习过面向对象的三要素之封装和继承。多态就是一个很简单的定义,在Python中多态的表现需要满足两个要求即可。即继承父类且重写父类的方法。

     1 #!/usr/bin/env python
     2 #_*_conding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie
     5 
     6 
     7 class Animal:
     8     def __init__(self,name):
     9         self._name = name
    10 
    11     def shout(self):
    12         raise Exception("方法需要重写")
    13 
    14 class Cat(Animal):
    15     def shout(self):
    16         print("喵喵喵~")
    17 
    18 class Dog(Animal):
    19     def shout(self):
    20         print("汪汪汪~")
    21 
    22 
    23 c = Cat("布偶")
    24 c.shout()
    25 
    26 d = Dog("二哈")
    27 d.shout()
    28 
    29 
    30 #以上代码执行结果如下:
    31 喵喵喵~
    32 汪汪汪~

     

    三.小试牛刀

    1>.Shape基类,要求所有子类都必须提供面积的计算,子类有三角形,矩形,圆(多态应用)

    2>.上体圆类的数据可序列化。(Mixin)

    3>.链表实现

      用面向对象实现LinkedList链表
      单向链表实现append,iternodes方法
      双向链表实现append,pop,insert,remove,iternodes方法
     1 #!/usr/bin/env python
     2 #_*_conding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie
     5 
     6 """
     7     用面向对象实现LinkedList链表
     8     单向链表实现append,iternodes方法
     9     双向链表实现append,pop,insert,remove,iternodes方法
    10 """
    11 
    12 class SingleNode:           #节点保存内容和下一条
    13     def __init__(self,item,next=None):
    14         self.item = item
    15         self.next = next
    16 
    17     def __repr__(self):
    18         return repr(self.item)
    19 
    20 class LinkList:
    21     def __init__(self):
    22         self.head = None        #用于存储上一个SingleNode的信息
    23         self.tail = None        #用于存储下一个SingleNode的信息
    24 
    25     def append(self,item):
    26         node = SingleNode(item)
    27         if self.head is None:
    28             self.head = node        #设置节点开头,以后不变
    29         else:
    30             self.tail.next = node   #当前最后一个节点关联下一个SingleNode
    31         self.tail = node            #更新结尾节点
    32         return self
    33 
    34     def iternodes(self):
    35         current = self.head
    36         while current:
    37             yield current
    38             current = current.next
    39 
    40 
    41 
    42 s = LinkList()
    43 s.append("尹正杰")
    44 s.append(100).append(200)
    45 s.append("Jason Yin")
    46 
    47 print(s.head)
    48 print(s.tail)
    49 
    50 print("{0} 我是分割线 {0}".format("*" * 15))
    51 
    52 for item in s.iternodes():
    53     print(item)
    54 
    55 
    56 
    57 
    58 
    59 #以上代码执行结果如下:
    60 '尹正杰'
    61 'Jason Yin'
    62 *************** 我是分割线 ***************
    63 '尹正杰'
    64 100
    65 200
    66 'Jason Yin'
    参考案例一(单项链表)
     1 #!/usr/bin/env python
     2 #_*_conding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie
     5 
     6 """
     7     用面向对象实现LinkedList链表
     8     单向链表实现append,iternodes方法
     9     双向链表实现append,pop,insert,remove,iternodes方法
    10 """
    11 
    12 class SingleNode:               #节点保存内容和下一条
    13     def __init__(self,item,next=None):
    14         self.item = item
    15         self.next = next
    16 
    17     def __repr__(self):
    18         return repr(self.item)
    19 
    20 class LinkList:
    21     def __init__(self):
    22         self.head = None
    23         self.tail = None
    24         self.items = []                 #只有节点自己知道下一跳是谁,想直接访问某一个节点只能遍历。借助列表就可以方便的随机访问某一个结点了。
    25 
    26     def append(self,item):
    27         node = SingleNode(item)
    28         if self.head is None:
    29             self.head = node            #设置开头,以后不变
    30         else:
    31             self.tail.next = node       #当前最后一个节点关联吓一跳
    32         self.tail = node                #更新结尾结点
    33 
    34         self.items.append(node)
    35         return self
    36 
    37     def iternodes(self):
    38         current = self.head
    39         while current:
    40             yield current
    41             current = current.next
    42 
    43     def getitem(self,index):
    44         return self.items[index]
    45 
    46 s = LinkList()
    47 s.append("Python")
    48 s.append(200).append(300)
    49 s.append("Java")
    50 
    51 print(s.head,s.tail)
    52 
    53 print("{0} 我是分割线 {0}".format("*" * 15))
    54 
    55 for item in s.iternodes():
    56     print(item)
    57 
    58 print("{0} 我是分割线 {0}".format("*" * 15))
    59 
    60 for i in range(len(s.items)):
    61     print(s.getitem(i))
    62 
    63 
    64 
    65 #以上代码执行结果如下:
    66 'Python' 'Java'
    67 *************** 我是分割线 ***************
    68 'Python'
    69 200
    70 300
    71 'Java'
    72 *************** 我是分割线 ***************
    73 'Python'
    74 200
    75 300
    76 'Java'
    参考案例二(单项链表基于列表实现)
      1 #!/usr/bin/env python
      2 #_*_conding:utf-8_*_
      3 #@author :yinzhengjie
      4 #blog:http://www.cnblogs.com/yinzhengjie
      5 
      6 """
      7     用面向对象实现LinkedList链表
      8     单向链表实现append,iternodes方法
      9     双向链表实现append,pop,insert,remove,iternodes方法
     10 """
     11 
     12 class SingleNode:           #节点保存内容和下一条
     13     def __init__(self,item,prev=None,next=None):
     14         self.item = item
     15         self.next = next
     16         self.prev = prev        #增加上一跳属性
     17 
     18     def __repr__(self):
     19         return "(prev:{}<==item:{}==>next:{})".format(
     20             self.prev.item if self.prev else None,
     21             self.item,
     22             self.next.item if self.next else None
     23         )
     24 
     25 class LinkList:
     26     def __init__(self):
     27         self.head = None
     28         self.tail = None
     29         self.size = 0
     30 
     31     def append(self,item):
     32         node = SingleNode(item)
     33         if self.head is None:
     34             self.head = node                #设置开头节点,以后不变
     35         else:
     36             self.tail.next = node           #当前最后一个节点关联下一跳
     37             node.prev = self.tail           #前后关联
     38         self.tail = node                    #更新尾结点
     39         return self
     40 
     41     def insert(self,index,item):
     42         if index < 0:                       #不接受负数
     43             raise IndexError("Not negative index {}".format(index))
     44         current = None
     45         for i,node in enumerate(self.iternodes()):
     46             if i == index:                  #找到了
     47                 current = node
     48                 break
     49         else:                               #没有break,尾部追加
     50             self.append(item)
     51             return
     52 
     53         node = SingleNode(item)
     54         prev = current.prev
     55         next = current
     56         if prev is None:            #首部
     57             self.head = node
     58         else:                       #不是首元素
     59             prev.next = node
     60             node.prev = prev
     61 
     62         node.next = next
     63         next.prev = node
     64 
     65 
     66     def pop(self):
     67         if self.tail is None:       #
     68             raise Exception("Empty")
     69 
     70         node = self.tail
     71         item = node.item
     72         prev = node.prev
     73 
     74         if prev is None:
     75             self.head = None
     76             self.tail = None
     77         else:
     78             prev.next = None
     79             self.tail = prev
     80         return item
     81 
     82     def remove(self,index):
     83         if self.tail is None:       #
     84             raise Exception("Empty")
     85 
     86         if index < 0:               #不接受负数
     87             raise IndexError("Not nagative index {}".format(index))
     88 
     89         current = None
     90         for i,node in enumerate(self.iternodes()):
     91             if i == index:
     92                 current = node
     93                 break
     94         else:
     95             raise IndexError("wrong index {}".format(index))
     96 
     97         prev = current.prev
     98         next = current.next
     99 
    100         if prev is None and next is None:
    101             self.head = None
    102             self.tail = None
    103         elif prev is None:      #头部
    104             self.head = next
    105             next.prev = None
    106         elif next is None:      #尾部
    107             self.tail = prev
    108             prev.next = None
    109         else:                   #在中间
    110             prev.next = next
    111             next.prev = prev
    112 
    113         del current
    114 
    115     def iternodes(self,reverse=False):
    116         current = self.tail if reverse else  self.head
    117         while current:
    118             yield current
    119             current = current.prev if reverse else current.next
    120 
    121 s = LinkList()
    122 s.append("100")
    123 s.append(200).append(300)
    124 s.append("400")
    125 
    126 print(s.head,s.tail)
    127 
    128 print("{0} 我是分割线 {0}".format("*" * 15))
    129 
    130 for item in s.iternodes(True):
    131     print(item)
    132 
    133 print("{0} 我是分割线 {0}".format("*" * 15))
    134 
    135 s.remove(1)
    136 s.remove(2)
    137 
    138 print("{0} 我是分割线 {0}".format("*" * 15))
    139 
    140 for item in s.iternodes():
    141     print(item)
    142 
    143 s.insert(3,520)
    144 s.insert(20,"888888")
    145 s.insert(0,"66666")
    146 
    147 print("{0} 我是分割线 {0}".format("*" * 15))
    148 
    149 for item in s.iternodes():
    150     print(item)
    151 
    152 
    153 
    154 
    155 #以上代码执行结果如下:
    156 (prev:None<==item:100==>next:200) (prev:300<==item:400==>next:None)
    157 *************** 我是分割线 ***************
    158 (prev:300<==item:400==>next:None)
    159 (prev:200<==item:300==>next:400)
    160 (prev:100<==item:200==>next:300)
    161 (prev:None<==item:100==>next:200)
    162 *************** 我是分割线 ***************
    163 *************** 我是分割线 ***************
    164 (prev:None<==item:100==>next:300)
    165 (prev:100<==item:300==>next:None)
    166 *************** 我是分割线 ***************
    167 (prev:None<==item:66666==>next:100)
    168 (prev:66666<==item:100==>next:300)
    169 (prev:100<==item:300==>next:520)
    170 (prev:300<==item:520==>next:888888)
    171 (prev:520<==item:888888==>next:None)
    参考案例三(实现单向链表没有实现的pop,remove,insert方法)

    4>.链表功能增强

        将前面的链表,封装成容器
        要求:
            提供__getitem__,__iter__,__setitem__方法

    5>.定义一个斐波拉契数列的类 

        定义一个斐波拉契数列的类,方便调用,计算第n项。
        增加迭代数列的方法,返回数列长度,支持索引查找数列项的方法。
  • 相关阅读:
    Computer Science Theory for the Information Age-4: 一些机器学习算法的简介
    Computer Science Theory for the Information Age-3: 高维空间中的高斯分布和随机投影
    Computer Science Theory for the Information Age-2: 高维空间中的正方体和Chernoff Bounds
    PrestaShop 1.7 如何添加网站的跟踪代码
    PrestaShop 1.7 创建税单的时候中文显示方框
    PrestaShop 1.7 首页菜单如何进行调整
    PrestaShop 1.7 如何启用 debug 模式
    PrestaShop 1.7.6 在访问分类的时候提示错误
    PrestaShop 1.7 安装完成后后台能进去,前台不行
    Maven 服务器如何设置用户名和密码
  • 原文地址:https://www.cnblogs.com/yinzhengjie/p/11179289.html
Copyright © 2011-2022 走看看