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项。
    增加迭代数列的方法,返回数列长度,支持索引查找数列项的方法。

 

posted @ 2019-07-13 06:05  尹正杰  阅读(797)  评论(0编辑  收藏  举报