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)
4>.链表功能增强
将前面的链表,封装成容器 要求: 提供__getitem__,__iter__,__setitem__方法。
5>.定义一个斐波拉契数列的类
定义一个斐波拉契数列的类,方便调用,计算第n项。
增加迭代数列的方法,返回数列长度,支持索引查找数列项的方法。
本文来自博客园,作者:尹正杰,转载请注明原文链接:https://www.cnblogs.com/yinzhengjie/p/11179289.html,个人微信: "JasonYin2020"(添加时请备注来源及意图备注,有偿付费)
当你的才华还撑不起你的野心的时候,你就应该静下心来学习。当你的能力还驾驭不了你的目标的时候,你就应该沉下心来历练。问问自己,想要怎样的人生。