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. SQL 对比,移动累计

    数据对比 两种常用模型 1.对比下一行,判断增长.减少.维持现状 -- 建表 drop table sales create table sales( num int, soc int ); inse ...

  2. (原)关于OpenGL中的几个坐标系统的理解

    在我们使用opengl做图像处理的过程中,其中必不可少的基本都会用到顶点着色器和片元着色器. 完整的渲染管线图: 那么在这两个着色器程序中,我们需要绘制我们的图像的时候,他们的坐标和位置对应关系是如何 ...

  3. BeetlConfiguration扩展配置

    beetl拓展配置类,绑定一些工具类,方便在模板中直接调用 BeetlConfiguration.java public class BeetlConfiguration extends BeetlG ...

  4. linux安装docker,并在docker上运行springboot项目

    docker架构示例图 仓库---> 镜像 --->  容器 一.安装docker 1.通过 uname -r 命令查看你当前的内核版本 uname -r 2使用 root 权限登录 Ce ...

  5. SQL Server 2019 新函数Approx_Count_Distinct

    2019年11月4日微软发布了2019正式版,该版本有着比以往更多强大的新功能和性能上的优势,可参阅SQL Server 2019 新版本. SQL Server 2019具有一组丰富的增强功能和新功 ...

  6. c++11多线程记录3: 数据争用和Mutex的使用

    https://www.youtube.com/watch?v=3ZxZPeXPaM4 学习视频 数据争用 简单来说就是存在多个线程同时对某个共同的对象进行读写(至少有一个线程在做写操作),造成读取这 ...

  7. Python使用Django创建第一个项目

    一 必要环境安装 1首先确保安装了Python3,在此使用的系统为Ubuntu @ubuntu:~$ python3 Python 3.6.7 (default, Oct 22 2018, 11:32 ...

  8. GIL全局解释锁,死锁,信号量,event事件,线程queue,TCP服务端实现并发

    一.GIL全局解释锁 在Cpython解释器才有GIL的概念,不是python的特点 在Cpython解释器中,同一个进程下开启的多线程,同一时刻只能有一个线程执行,无法利用多核优势. 1.GIL介绍 ...

  9. 【1】【leetcode-72 动态规划】 编辑距离

    (没思路,很典型,重要) 给定两个单词 word1 和 word2,计算出将 word1 转换成 word2 所使用的最少操作数 . 你可以对一个单词进行如下三种操作: 插入一个字符 删除一个字符 替 ...

  10. HBase 系列(一)—— HBase 简介

    一.Hadoop的局限 HBase 是一个构建在 Hadoop 文件系统之上的面向列的数据库管理系统. 要想明白为什么产生 HBase,就需要先了解一下 Hadoop 存在的限制?Hadoop 可以通 ...