Python面向对象3要素-多态

                                 作者:尹正杰

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

 一.多态概述

  OCP原则:多用“继承”,少修改。

  继承的用途:在子类上实现对基类的增强,实现多态。

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

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

  

二.多态案例

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

 #!/usr/bin/env python
#_*_conding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie class Animal:
def __init__(self,name):
self._name = name def shout(self):
raise Exception("方法需要重写") class Cat(Animal):
def shout(self):
print("喵喵喵~") class Dog(Animal):
def shout(self):
print("汪汪汪~") c = Cat("布偶")
c.shout() d = Dog("二哈")
d.shout() #以上代码执行结果如下:
喵喵喵~
汪汪汪~

三.小试牛刀

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

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

3>.链表实现

  用面向对象实现LinkedList链表
  单向链表实现append,iternodes方法
  双向链表实现append,pop,insert,remove,iternodes方法
 #!/usr/bin/env python
#_*_conding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie """
用面向对象实现LinkedList链表
单向链表实现append,iternodes方法
双向链表实现append,pop,insert,remove,iternodes方法
""" class SingleNode: #节点保存内容和下一条
def __init__(self,item,next=None):
self.item = item
self.next = next def __repr__(self):
return repr(self.item) class LinkList:
def __init__(self):
self.head = None #用于存储上一个SingleNode的信息
self.tail = None #用于存储下一个SingleNode的信息 def append(self,item):
node = SingleNode(item)
if self.head is None:
self.head = node #设置节点开头,以后不变
else:
self.tail.next = node #当前最后一个节点关联下一个SingleNode
self.tail = node #更新结尾节点
return self def iternodes(self):
current = self.head
while current:
yield current
current = current.next s = LinkList()
s.append("尹正杰")
s.append(100).append(200)
s.append("Jason Yin") print(s.head)
print(s.tail) print("{0} 我是分割线 {0}".format("*" * 15)) for item in s.iternodes():
print(item) #以上代码执行结果如下:
'尹正杰'
'Jason Yin'
*************** 我是分割线 ***************
'尹正杰'
100
200
'Jason Yin'

参考案例一(单项链表)

 #!/usr/bin/env python
#_*_conding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie """
用面向对象实现LinkedList链表
单向链表实现append,iternodes方法
双向链表实现append,pop,insert,remove,iternodes方法
""" class SingleNode: #节点保存内容和下一条
def __init__(self,item,next=None):
self.item = item
self.next = next def __repr__(self):
return repr(self.item) class LinkList:
def __init__(self):
self.head = None
self.tail = None
self.items = [] #只有节点自己知道下一跳是谁,想直接访问某一个节点只能遍历。借助列表就可以方便的随机访问某一个结点了。 def append(self,item):
node = SingleNode(item)
if self.head is None:
self.head = node #设置开头,以后不变
else:
self.tail.next = node #当前最后一个节点关联吓一跳
self.tail = node #更新结尾结点 self.items.append(node)
return self def iternodes(self):
current = self.head
while current:
yield current
current = current.next def getitem(self,index):
return self.items[index] s = LinkList()
s.append("Python")
s.append(200).append(300)
s.append("Java") print(s.head,s.tail) print("{0} 我是分割线 {0}".format("*" * 15)) for item in s.iternodes():
print(item) print("{0} 我是分割线 {0}".format("*" * 15)) for i in range(len(s.items)):
print(s.getitem(i)) #以上代码执行结果如下:
'Python' 'Java'
*************** 我是分割线 ***************
'Python'
200
300
'Java'
*************** 我是分割线 ***************
'Python'
200
300
'Java'

参考案例二(单项链表基于列表实现)

 #!/usr/bin/env python
#_*_conding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie """
用面向对象实现LinkedList链表
单向链表实现append,iternodes方法
双向链表实现append,pop,insert,remove,iternodes方法
""" class SingleNode: #节点保存内容和下一条
def __init__(self,item,prev=None,next=None):
self.item = item
self.next = next
self.prev = prev #增加上一跳属性 def __repr__(self):
return "(prev:{}<==item:{}==>next:{})".format(
self.prev.item if self.prev else None,
self.item,
self.next.item if self.next else None
) class LinkList:
def __init__(self):
self.head = None
self.tail = None
self.size = 0 def append(self,item):
node = SingleNode(item)
if self.head is None:
self.head = node #设置开头节点,以后不变
else:
self.tail.next = node #当前最后一个节点关联下一跳
node.prev = self.tail #前后关联
self.tail = node #更新尾结点
return self def insert(self,index,item):
if index < 0: #不接受负数
raise IndexError("Not negative index {}".format(index))
current = None
for i,node in enumerate(self.iternodes()):
if i == index: #找到了
current = node
break
else: #没有break,尾部追加
self.append(item)
return node = SingleNode(item)
prev = current.prev
next = current
if prev is None: #首部
self.head = node
else: #不是首元素
prev.next = node
node.prev = prev node.next = next
next.prev = node def pop(self):
if self.tail is None: #空
raise Exception("Empty") node = self.tail
item = node.item
prev = node.prev if prev is None:
self.head = None
self.tail = None
else:
prev.next = None
self.tail = prev
return item def remove(self,index):
if self.tail is None: #空
raise Exception("Empty") if index < 0: #不接受负数
raise IndexError("Not nagative index {}".format(index)) current = None
for i,node in enumerate(self.iternodes()):
if i == index:
current = node
break
else:
raise IndexError("wrong index {}".format(index)) prev = current.prev
next = current.next if prev is None and next is None:
self.head = None
self.tail = None
elif prev is None: #头部
self.head = next
next.prev = None
elif next is None: #尾部
self.tail = prev
prev.next = None
else: #在中间
prev.next = next
next.prev = prev del current def iternodes(self,reverse=False):
current = self.tail if reverse else self.head
while current:
yield current
current = current.prev if reverse else current.next s = LinkList()
s.append("")
s.append(200).append(300)
s.append("") print(s.head,s.tail) print("{0} 我是分割线 {0}".format("*" * 15)) for item in s.iternodes(True):
print(item) print("{0} 我是分割线 {0}".format("*" * 15)) s.remove(1)
s.remove(2) print("{0} 我是分割线 {0}".format("*" * 15)) for item in s.iternodes():
print(item) s.insert(3,520)
s.insert(20,"")
s.insert(0,"") print("{0} 我是分割线 {0}".format("*" * 15)) for item in s.iternodes():
print(item) #以上代码执行结果如下:
(prev:None<==item:100==>next:200) (prev:300<==item:400==>next:None)
*************** 我是分割线 ***************
(prev:300<==item:400==>next:None)
(prev:200<==item:300==>next:400)
(prev:100<==item:200==>next:300)
(prev:None<==item:100==>next:200)
*************** 我是分割线 ***************
*************** 我是分割线 ***************
(prev:None<==item:100==>next:300)
(prev:100<==item:300==>next:None)
*************** 我是分割线 ***************
(prev:None<==item:66666==>next:100)
(prev:66666<==item:100==>next:300)
(prev:100<==item:300==>next:520)
(prev:300<==item:520==>next:888888)
(prev:520<==item:888888==>next:None)

参考案例三(实现单向链表没有实现的pop,remove,insert方法)

4>.链表功能增强

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

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

    定义一个斐波拉契数列的类,方便调用,计算第n项。
增加迭代数列的方法,返回数列长度,支持索引查找数列项的方法。

Python面向对象三要素-多态的更多相关文章

  1. Python面向对象三要素-继承(Inheritance)

    Python面向对象三要素-继承(Inheritance) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.继承概述 1>.基本概念 前面我们学习了Python的面向对象三 ...

  2. Python面向对象三要素-封装(Encapsulation)

    Python面向对象三要素-封装(Encapsulation) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.封装概述 将数据和操作组织到类中,即属性和方法 将数据隐藏起来,给 ...

  3. python面向对象(封装,继承,多态)

    python面向对象(封装,继承,多态) 学习完本篇,你将会深入掌握 如何封装一个优雅的借口 python是如何实现继承 python的多态 封装 含义: 1.把对象的属性和方法结合成一个独立的单位, ...

  4. Python面向对象(三)

    一.绑定方法与非绑定方法 一.绑定方法:绑定给谁就应该由谁来调用,谁来调用就会将谁当作第一个参数传入 1.绑定给对象的方法:类中定义的函数默认就是绑定给对象的 2.绑定给类的方法:为类中定义的函数加上 ...

  5. python 面向对象(三)--继承和多态

    在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类.父类或超类(Base class.Supe ...

  6. python面向对象之继承/多态/封装

    老师说,按继承/多态/封装这个顺序来讲. 子类使用父类的方法: #!/usr/bin/env python # coding:utf-8 class Vehicle: def __init__(sel ...

  7. Python面向对象-继承和多态特性

    继承 在面向对象的程序设计中,当我们定义一个class时候,可以从现有的class继承,新的class成为子类,被继承的class称为基类,父类或超类. 比如,编写一个名为Animal的class: ...

  8. python面向对象(封装、多态、反射)

    目录 面向对象之封装 @property 面向对象之多态 面向对象之反射 面向对象之封装 含义 将类中的某些名字按照特殊的书写方式"隐藏"起来,不让外界直接调用,目的是为了不然外界 ...

  9. Python面向对象 -- 继承和多态、获取对象信息、实例属性和类属性

    继承和多态 继承的好处: 1,子类可以使用父类的全部功能 2,多态:当子类和父类都存在相同的方法时,子类的方法会覆盖父类的方法,即调用时会调用子类的方法.这就是继承的另一个好处:多态. 多态: 调用方 ...

随机推荐

  1. Jmetal设置Solution Variables

    Jmetal设置Solution Variables 觉得有用的话,欢迎一起讨论相互学习~Follow Me 首先每个solution都必须使用Problemset初始化 ProblemSet pro ...

  2. EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器开放平台利用 webpack 打包压缩后端代码

    需求背景 javaScript的用途是解决页面交互和数据交互,最终目的是丰富客户端效果以及数据的有效传递. 并且具有良好的用户体验. javaScript可以快速实现页面交互,即js操作html的do ...

  3. [转]Ubuntu18.04 主题美化以及常用软件

    原文地址:https://www.jianshu.com/p/7d153a484f72

  4. 在Django中显示操作数据库的语句

    需要在配置中加上这个 LOGGING = { 'version':1, 'disable_existing_loggers':False, 'handlers':{ 'console':{ 'leve ...

  5. PIL和Pillow

    关于Pillow与PIL PIL(Python Imaging Library)是Python一个强大方便的图像处理库,名气也比较大.不过只支持到Python 2.7. PIL官方网站:http:// ...

  6. linux install jsoncpp0.5.0

    要安装jsoncpp,首先要下载好scons,再去安装jsoncpp scons下载地址:wget http://prdownloads.sourceforge.NET/scons/scons-2.2 ...

  7. nginx 进程问题

    1 nginx的进程分为四种 master worker cacheLoader cacheManager. 实际接收请求的进程是 worker,master监控worker节点,之所以会多进程模式, ...

  8. 【剑指offer】数组在排序数组中出现的次数

    题目描述 统计一个数字在排序数组中出现的次数. 分析:数组有序,采用二分查找无疑 两种方法,时间复杂度差不多,都是利用二分查找,不过统计k出现的次数有所不同而已 方法1:二分查找k,找到任意一个k的下 ...

  9. IUrlHelper ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index

    ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of ...

  10. 洛谷--P1028 数的计算(递推)

    题意:链接:https://www.luogu.org/problem/P1028 先输入一个自然数n (n≤1000) , 然后对此自然数按照如下方法进行处理: 不作任何处理; 在它的左边加上一个自 ...