Python面向对象三要素-多态
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面向对象三要素-多态的更多相关文章
- Python面向对象三要素-继承(Inheritance)
Python面向对象三要素-继承(Inheritance) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.继承概述 1>.基本概念 前面我们学习了Python的面向对象三 ...
- Python面向对象三要素-封装(Encapsulation)
Python面向对象三要素-封装(Encapsulation) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.封装概述 将数据和操作组织到类中,即属性和方法 将数据隐藏起来,给 ...
- python面向对象(封装,继承,多态)
python面向对象(封装,继承,多态) 学习完本篇,你将会深入掌握 如何封装一个优雅的借口 python是如何实现继承 python的多态 封装 含义: 1.把对象的属性和方法结合成一个独立的单位, ...
- Python面向对象(三)
一.绑定方法与非绑定方法 一.绑定方法:绑定给谁就应该由谁来调用,谁来调用就会将谁当作第一个参数传入 1.绑定给对象的方法:类中定义的函数默认就是绑定给对象的 2.绑定给类的方法:为类中定义的函数加上 ...
- python 面向对象(三)--继承和多态
在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类.父类或超类(Base class.Supe ...
- python面向对象之继承/多态/封装
老师说,按继承/多态/封装这个顺序来讲. 子类使用父类的方法: #!/usr/bin/env python # coding:utf-8 class Vehicle: def __init__(sel ...
- Python面向对象-继承和多态特性
继承 在面向对象的程序设计中,当我们定义一个class时候,可以从现有的class继承,新的class成为子类,被继承的class称为基类,父类或超类. 比如,编写一个名为Animal的class: ...
- python面向对象(封装、多态、反射)
目录 面向对象之封装 @property 面向对象之多态 面向对象之反射 面向对象之封装 含义 将类中的某些名字按照特殊的书写方式"隐藏"起来,不让外界直接调用,目的是为了不然外界 ...
- Python面向对象 -- 继承和多态、获取对象信息、实例属性和类属性
继承和多态 继承的好处: 1,子类可以使用父类的全部功能 2,多态:当子类和父类都存在相同的方法时,子类的方法会覆盖父类的方法,即调用时会调用子类的方法.这就是继承的另一个好处:多态. 多态: 调用方 ...
随机推荐
- springboot+mybatisplus+druid数据库
1.添加maven依赖 <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis ...
- 【Docker学习之二】Docker部署安装
环境 docker-ce-19.03.1-3.el7.x86_64 一.Docker的部署安装 Docker采用Linux(内核)技术,所以只能运行在Linux上,官方说Linux kernel至少3 ...
- Kafka Connect简介
Kafka Connect简介 http://colobu.com/2016/02/24/kafka-connect/#more Kafka 0.9+增加了一个新的特性Kafka Connect,可以 ...
- B+树比B树更适合实际应用中操作系统的文件索引和数据库索引
B+树比B树更适合实际应用中操作系统的文件索引和数据库索引 为什么选择B+树作为数据库索引结构? 背景 首先,来谈谈B树.为什么要使用B树?我们需要明白以下两个事实: [事实1]不同容量的存储器, ...
- 研发的困境----DEVOPS
1.研发的困境 互联网的环境 互联网这个环境比较特别,包括现在不只是互联网,就算是被互联网赋能的这些“互联网+”的企业也在改变,用户在发生变化,用户构成的群体在发生变化,群体造成场景的变化,场景营造新 ...
- SpringBoot整合websocket
1.新增pom依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId& ...
- react中的ref在input中的详解
当我们在项目中遇见文本输入框的时候,获取时刻输入框中的值 1.受控组件 class NameForm extends React.Component { constructor(props) { su ...
- 【转帖】HBase之五:hbase的region分区
HBase之五:hbase的region分区 https://www.cnblogs.com/duanxz/p/3154487.html 一.Region 概念 Region是表获取和分布的基本元素, ...
- python入门基础 03
整型 -- 数字 (int) 用于比较和运算的 32位 -2 ** 31 -1 ~ 2 ** 31 -1 64位 -2 ** 63 -1 ~ 2 ** 63 -1 + - * / // ** % &q ...
- 【EBS】菜单的复制脚本
DECLARE l_error_flag ); l_menu_rowid ); l_menu_entity_rowid ); l_menu_id NUMBER; l_cnt ; c_new_menu_ ...