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项。
        增加迭代数列的方法,返回数列长度,支持索引查找数列项的方法。
  • 相关阅读:
    再次或多次格式化导致namenode的ClusterID和datanode的ClusterID之间不一致的问题解决办法
    Linux安装aria2
    POJ 3335 Rotating Scoreboard 半平面交
    hdu 1540 Tunnel Warfare 线段树 区间合并
    hdu 3397 Sequence operation 线段树 区间更新 区间合并
    hud 3308 LCIS 线段树 区间合并
    POJ 3667 Hotel 线段树 区间合并
    POJ 2528 Mayor's posters 贴海报 线段树 区间更新
    POJ 2299 Ultra-QuickSort 求逆序数 线段树或树状数组 离散化
    POJ 3468 A Simple Problem with Integers 线段树成段更新
  • 原文地址:https://www.cnblogs.com/yinzhengjie/p/11179289.html
Copyright © 2011-2022 走看看