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. kubernetes 1.9 安装部署

    参考地址:https://github.com/gjmzj/kubeasz 引言 提供快速部署高可用k8s集群的工具,基于二进制方式部署和利用ansible-playbook实现自动化,既提供一键安装 ...

  2. Java8学习之异步编程

    异步编程 所谓异步其实就是实现一个无需等待被调用函数的返回值而让操作继续运行的方法 创建任务并执行任务 无参创建 CompletableFuture<String> noArgsFutur ...

  3. python:时间格式转化

    1.获取秒级时间戳与毫秒级时间戳.微秒级时间戳 import time import datetime t = time.time() print (t) #原始时间数据 print (int(t)) ...

  4. JS如何实现继承?

    JS的继承是基于JS类的基础上的一种代码复用机制.换言之,有了代码,我们就不需要复制之前写好的方法,只要通过简捷的方式 复用之前自己写的或同事写的代码.比如一个弹出层,我们需要在上面做一些修改.同事写 ...

  5. SQL Server sp_monitor使用

    SQL Server提供了sp_monitor存储过程可以方便我们查看SQL Server性能统计信息,包括CPU/Network/IO,通过这些信息可以对自己的数据库性能状况有一个大致的了解. 下面 ...

  6. Anaconda的pip加速下载命令

    pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

  7. Win10各个PC版本的差别

    新的电脑有的已经不能够支持安装win7了,也就是说新电脑的硬件支持只能安装win10.那么win10有都有那些版本呢?这些版本之间又有什么样区别?我相信很多人并不是很了解.今天就来整理一下这些资料.据 ...

  8. Spark之RDD容错原理及四大核心要点

    一.Spark RDD容错原理 RDD不同的依赖关系导致Spark对不同的依赖关系有不同的处理方式. 对于宽依赖而言,由于宽依赖实质是指父RDD的一个分区会对应一个子RDD的多个分区,在此情况下出现部 ...

  9. 高并发场景下System.currentTimeMillis()的性能问题的优化

    高并发场景下System.currentTimeMillis()的性能问题的优化 package cn.ucaner.alpaca.common.util.key; import java.sql.T ...

  10. .net Aop 实现原理

    本文实现所有继承BaseModel的类都通过代理拦截 using System; using System.Reflection; using System.Collections.Generic; ...