Python笔记(二十)_多态、组合
多态
对于函数中的变量,我们只需要知道它这个变量是什么类,无需确切地知道它的子类型,就可以放心地调用类的方法,而具体调用的这个方法是作用在父类对象还是子类对象上,由运行时该对象的确切类型决定,这就是多态真正的威力
>>>class Animal: #定义一个父类
def run(self):
print('animal is running...')
>>>class Dog(Animal): #继承于Animal类
def run(self):
print('Dog is running...')
>>>class Cat(Animal): #继承于Animal类
def run(self):
print('Cat is running...')
>>>def run_twice(animal): #此处新建一个函数,且此函数接受一个animal类型的变量
animal.run()
animal.run()
当我们传入Animal的实例时,run_twice()就打印出:
>>>run_twice(Animal())
Animal is running...
Animal is running...
当我们传入Dog的实例时,run_twice()就打印出:
>>>run_twice(Dog())
Dog is running...
Dog is running...
当我们传入Cat的实例时,run_twice()就打印出:
>>>run_twice(Cat())
Cat is running...
Cat is running...
如果我们再定义一个Tortoise类型,也从Animal派生:
>>>class Tortoise(Animal):
def run(self):
print('Tortoise is running slowly...')
当我们调用run_twice()时,传入Tortoise的实例:
>>>run_twice(Tortoise())
Tortoise is running slowly...
Tortoise is running slowly...
由上可以发现,多态的好处就是,当我们需要传入Dog、Cat、Tortoise……时,我们只需要接收Animal类型就可以了。然后,按照Animal类型进行操作即可,由于Animal类型有run()方法,因此,传入的任意类型,只要是Animal类或者子类,就会自动调用实际类型的run()方法,这就是多态的意思。
调用方只管调用,不管细节,而当我们新增一种父类的子类时,只要确保类的方法编写正确,不用管原来的代码是如何调用的。这个就是著名的“开闭”原则:
对扩展开放:允许新增Animal子类;
对修改封闭:不需要修改依赖Animal类型的run_twice()等函数
由于python是动态语言,所以run_twice()中不一定必须传入Animal类型,只要保证传入的对象有一个run()方法就可以了,上述结论就是动态语言的鸭子类型,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。
>>>class Demi:
def run(self):
print('demi is a girl')
>>>run_twice(Demi())
demi is a girl
demi is a girl
组合
组合指的是,在一个类中以另外一个类的实例对象作为数据属性
作用是可以将两个本来不相关的类联系起来,一般是两个类之间有显著的不同
>>>class Turtle:
def __init__(self,x):
self.num = x
>>>class Fish:
def __init__(self,x):
self.num = x
>>>class Pool:
def __init__(self,x,y):
self.turtle = Turtle(x)
self.fish = Fish(y)
def number(self):
print("水池里总共%s只乌龟,共%s条鱼" % (self.turtle.num,self.fish.num))
有纵向关系用继承,无纵向关系用组合
简单的说,组合用于“有一个”的场景中,继承用于“是一个”的场景中。例如,水池里有一个乌龟,天上有一个鸟,这些适合使用组合。青瓜是瓜,女人是人,鲨鱼是鱼,这些就应该使用继承
Python笔记(二十)_多态、组合的更多相关文章
- Python笔记(二十九)_模块
模块 在Python中,一个.py文件就是一个模块 if __name__ == '__main__':所有模块都有一个 __name__ 属性,__name__ 的值取决于如何应用模块 run当前文 ...
- Python笔记(二十六)_魔法方法_属性的魔法方法
属性的魔法方法 __getattribute__(self,name):当该类的属性被访问时,自动触发,是最先被触发的属性方法 __setattr__(self,name,value):当一个属性被设 ...
- Python笔记(二十四)_魔法方法_运算符的魔法方法
算数运算方法 .反运算方法 以对象A+对象B为例,都是将A作为self值,而B作为other值传入__add__(self,other)方法: 当用户输入A+B,就会调用重写的add方法: >& ...
- Python笔记(二十二)_魔法方法_基本魔法方法
__init__(self[,...]) __init__和__new__组成python的构造器,但__init__更多的是负责初始化操作,相当于一个项目中的配置文件,__new__才是真正的构造函 ...
- Python笔记(二十八)_魔法方法_迭代器
迭代器用于遍历容器中的数据,但它不是容器,它是一个实现了__next__方法的对象 与迭代器相关的内置函数: iter(): 将一个对象转换成一个迭代器 next(): 访问迭代器中的下一个变量,直到 ...
- Python笔记(二十五)_魔法方法_描述符
描述符的属性方法 __get__(self, instance, owner): 用于访问属性,返回属性的值 __set__(self, instance, value): 用于给属性赋值时,返回属性 ...
- Python爬虫(二十)_动态爬取影评信息
本案例介绍从JavaScript中采集加载的数据.更多内容请参考:Python学习指南 #-*- coding:utf-8 -*- import requests import re import t ...
- [b0035] python 归纳 (二十)_多进程数据共享和同步_共享内存Value & Array
1. Code # -*- coding: utf-8 -*- """ 多进程 数据共享 共享变量 Value,Array 逻辑: 2个进程,对同一份数据,一个做加法,一 ...
- Python笔记(二十七)_魔法方法_容器
定制容器 容器类型的协议: 定制不可变容器,只需要定义__len__()和__getitem__()方法 定制可变容器,需要定义__len__().__getitem__().__setitem__( ...
随机推荐
- Fiddler用法整理
目 录 1 Fiddler的基本介绍 1.1 下载安装 1.2 适用平台 2 Fiddler的工作原理 3 同类工具 4 捕获非IE浏览器的会话 5 捕获不同请求的设置方法 5.1 Web HTTPS ...
- Python所有转义字符总汇
转义字符就是让程序按照已经设置好的字符输出,不然程序当成其他的输出了,下面总结所有python转义字符 \\ 反斜杠符号\' 单引号\" 双引号\a 响铃\b 退格(Backspace)\e ...
- docker私有仓库部署
首先科普docker几种“仓库”概念,可分为:本地镜像,本地仓库,公有仓库(docker hub) 本地镜像:在把java程序打包成镜像,输出的镜像的位置就是本地镜像 公有仓库:一个叫docker h ...
- 06-File-文件
文件 长久保存信息的一种数据信息集合 常用操作 打开关闭(文件一旦打开,需要关闭操作) 读写内容 查找 open函数 open函数负责打开文件,带有很多参数 第一个参数: 必须有,文件的路径和名称 m ...
- 命令行运行python -m http.server报错
最近在学习网站搭建,借助python搭建服务器时,在网站目录启动python服务时报错,如下: UnicodeDecodeError: 'utf-8' codec can't decode byte ...
- jQuery学习总结02-属性
1.attr(name|properties|key,value|fn) 说明:设置和返回被选元素的属性值 示例: 参数: name(属性名称) string properties(作为属性的'名/值 ...
- rabbit localhost不能登录
解决方案 将C:\Users\{用户名}\.erlang.cookie 复制到 C:\Windows\System32\config\systemprofile 目录. 重启rabbitMQ服务 [转 ...
- Redis分布式锁【正确实现方式】
前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...
- Linux ssh内置sftp配置说明
centos7 环境下已验证 首先建立两个用户,用于sftp访问使用. eg: useradd -d /opt/sftp -s /bin/nologin sftp 说明 -s /bin/nologi ...
- java判断回文数