Python进阶(十六)----面向对象之~封装,多态,鸭子模型,super原理(单继承原理,多继承原理)

一丶封装 , 多态

封装:

           将一些东西封装到一个地方,你还可以取出来(把一些内容装到某个容器内,用到这些内容还能取出来)

           类设置静态属性, 设置一些方法 或者 对象, 对象可以在其对象封装一些属性

多态:

           python默认支持多态, 多态指的是一种事务具有多种形态

           多态的优点:

           1.多态可以增加代码的灵活度;

           2.以继承和重写父类方法为前提;

           3.是调用方法的技巧,不会影响到类的内部设计

           个人理解: 接口(存放功能相类似的函数)重用,一种接口多种实现(通过接口调用相对应的函数)

#### 例1:
#序列类型有多种形态:字符串,列表,元组,但他们直接没有直接的继承关系 #str,list,tuple都是序列类型
s=str('hello')
l=list([1,2,3])
t=tuple((4,5,6)) #我们可以在不考虑三者类型的前提下使用s,l,t
s.__len__() # 三者的序列类型 都有__len_()方法,
l.__len__()
t.__len__() len(s) # len函数就具有多种形态
len(l)
len(t) # 解释: len函数就是一种事务, 元组,列表,字符就是多种形态.因为它们三者都含有__len__()函数 #### 例2: import abc
class Animal(metaclass=abc.ABCMeta): #同一类事物:动物
@abc.abstractmethod
def talk(self):
pass class People(Animal): #动物的形态之一:人
def talk(self):
print('say hello') class Dog(Animal): #动物的形态之二:狗
def talk(self):
print('say wangwang') class Pig(Animal): #动物的形态之三:猪
def talk(self):
print('say aoao') peo=People()
dog=Dog()
pig=Pig() #peo、dog、pig都是动物,只要是动物肯定有talk方法
#于是我们可以不用考虑它们三者的具体是什么类型,而直接使用
peo.talk()
dog.talk()
pig.talk() #更进一步,我们可以定义一个统一的接口来使用
def func(obj):
obj.talk()

鸭子模型:是动态类型的一种风格

      定义:

           当看到一只鸟走起来像鸭子,游泳起来像鸭子,叫起来也像鸭子,那么这只鸟就可以被称为鸭子.

      概念:

           在鸭子类型中,关注的不是对象的类型本身,而是它是如何使用的。例如,在不使用鸭子类型的语言中,我们可以编写一个函数,它接受一个类型为鸭的对象,并调用它的走和叫方法。在使用鸭子类型的语言中,这样的一个函数可以接受一个任意类型的对象,并调用它的走和叫方法。如果这些需要被调用的方法不存在,那么将引发一个运行时错误。任何拥有这样的正确的走和叫方法的对象都可被函数接受的这种行为引出了以上表述,这种决定类型的方式因此得名。鸭子类型通常得益于不测试方法和函数中参数的类型,而是依赖文档、清晰的代码和测试来确保正确使用。从静态类型语言转向动态类型语言的用户通常试图添加一些静态的(在运行之前的)类型检查,从而影响了鸭子类型的益处和可伸缩性,并约束了语言的动态特性。(摘自CSDN juunny,仅供参考)

class A:

    def login(self):
pass def register(self):
pass class B: def login(self):
pass def register(self):
pass # A,B两个类,没有任何关系,独立两个,但是里面的功能相似,所以python一般会将类似于A,B两个类
# 里面的相似的功能让其命名相同.
# A,B虽然无关系,但是很默契的制定了一个规范.让你使用起来更方便. ## 个人理解:
#你可以定义一个公共的接口, 简化代码 .牛逼人都这么干
def func(obj):
obj.register()
obj.login()

       一篇详细的多态文章

二丶类的约束

归一化设计:

           统一接口

###  pay函数就作为 统一的接口  不论用哪个平台调用都是使用pay函数

class QQ(Payment):
def pay(self,money):
print(f'支付了 {money}') class Ali(Payment):
def pay(self,money):
print(f'支付了 {money}') class WeChat(Payment):
def fuqian(self,money):
print(f'支付了 {money}') # 定义接口函数
def pay(obj,money):
obj.pay(money) q=QQ() # 实例化对象
a=Ali()
w=WeChat() pay(q,200) # 调用接口 实现功能
pay(a,100)
pay(w,1200)

父类建立一种约束

### 父类的约束不是强制性的,不重写父类的 pay函数 也可以调用子类本身的函数,完成支付功能

class Payment:			

    def pay(self,money):
raise Exception('子类必须继承父类pay方法') # 当子类执行接口函数时,调用函数名与父类不一致,父类pay函数主动抛出一个异常 class QQ(Payment):
def pay(self,money):
print(f'支付了 {money}') class Ali(Payment):
def pay(self,money):
print(f'支付了 {money}') class WeChat(Payment):
def fuqian(self,money):
print(f'支付了 {money}') # 定义接口 def pay(obj,money):
obj.pay(money) q=QQ() # 实例化对象
a=Ali()
w=WeChat() pay(q,200)
pay(a,100)
pay(w,1200) # 由于 子类没有重写父类的pay方法, 父类会主动抛出一个异常

模拟抽象类(指定一种规范)的概念,建立一种约束.

### 强制性约束, 必须重写父类的方法 

from abc import abstractmethod, ABCMeta  # 导入抽象类 和 抽象元类

class Payment(metaclass=ABCMeta):     # 定义这个类是一个抽象类
@abstractmethod # 给父类的 pay 函数添加抽象方法装饰器. 当子类没有重写父类方法,实例化对象时,就会报错
def pay(self, money):
pass class QQ(Payment):
def pay(self, money):
print(f'支付了 {money}') class Ali(Payment):
def pay(self, money):
print(f'支付了 {money}') class WeChat(Payment):
def fuqian(self, money):
print(f'支付了 {money}') # 重写父类的pay函数,就不会报错. 不重写就会报错
def pay(self, money):
pass # 定义接口 def pay(obj, money):
obj.pay(money) q=QQ()
a=Ali()
w=WeChat() # 1. 实例化对象时, 就会报错. 必须重写父类的pay函数 , pay(q,200)
pay(a,100)
pay(w,1200) # 由于抽象方法引自与Java的抽象类. so 原理相同
### 抽象类 不能被实例化 ,只能被继承
aa=Payment()
# TypeError: Can't instantiate abstract class Payment with abstract methods pay

三丶super的深入理解

### super() 并不是 执行父类的方法

    # 单继承: super() 肯定执行父类的方法

	# 多继承:  super(S,self)严格按照self(就是当前对象) 从属于类的mro的执行顺序,执行 S类的下一位

class A:
def f1(self):
print('in A') class Foo(A):
def f1(self):
super(Foo,self).f1()
print('in Foo') # 2 按照继承顺序来执行,主动执行当前类的下一个类(按照继承顺序执行) , 执行Bar类 class Bar(A):
def f1(self):
print('in Bar') # 1 按照继承顺序来执行, 执行当前类的下一个类(按照继承顺序执行),已经定位到当前的Bar中的f1函数,就不再向上寻找. class Info(Foo,Bar): def f1(self):
super(Info,self).f1() # 从Info当前类开始 ,执行当前类的下一个类(按照继承顺序执行), 执行Foo类, 不写是默认从Info当前类super(Info,self).f1()=super().f1()
print('in Info f1') # 按照继承顺序来执行完毕后, 再执行Info obj = Info()
print(Info.mro()) # obj对象的 继承顺序[Info, Foo, Bar, A]
obj.f1()
# 结果: in Bar, in Foo , in Info f1 ####多继承 , super指定继承哪个类,就从这个类的下一个类执行
class A:
def f1(self):
print('in A') class Foo(A): def f1(self):
super().f1()
print('in Foo') class Bar(A): def f1(self): # self = obj
print('in Bar') class Info(Foo,Bar): def f1(self): # self = obj
super(Foo,self).f1() # 这里指定从Foo类继承. 按照多继承规则,会执行下一个类,也就是Bar
print('in Info f1') obj = Info()
obj.f1() # obj对象的 继承顺序[Info, Foo, Bar, A] # 结果 : in Bar, in Info f1

Python进阶(十六)----面向对象之~封装,多态,鸭子模型,super原理(单继承原理,多继承原理)的更多相关文章

  1. Python进阶(十五)----面向对象之~继承(单继承,多继承MRO算法)

    Python进阶(十五)----面向对象之~继承 一丶面向对象的三大特性:封装,继承,多态 二丶什么是继承 # 什么是继承 # b 继承 a ,b是a的子类 派生类 , a是b的超类 基类 父类 # ...

  2. python学习day19 面向对象(一)封装/多态/继承

    面向对象 封装思想:将同一类的函数函数封装到同一个py文件中,方便调用 面向对象也有封装的作用,将同一类的函数封装到一个类中 多态(鸭子模型):多种类型/多种形态 #,什么事鸭子模型 对于一个函数,p ...

  3. J2EE进阶(十六)Hibernate 中getHibernateTemplate()方法使用

    J2EE进阶(十六)Hibernate 中getHibernateTemplate()方法使用   spring 中获得由spring所配置的hibernate的操作对象,然后利用此对象进行,保存,修 ...

  4. Python进阶(十四)----空间角度研究类,类与类之间的关系

    Python进阶(十四)----空间角度研究类,类与类之间的关系 一丶从空间角度研究类 对象操作对象属性 class A(): address = '沙河' def __init__(self, na ...

  5. Python进阶(十二)----re模块

    Python进阶(十二)----re模块 一丶re模块 ​ re模块是python将正则表达式封装之后的一个模块.正则表达式模式被编译成一系列的字节码,然后由用C编写的匹配引擎执行. #正则表达式: ...

  6. Python进阶(十)----软件开发规范, time模块, datatime模块,random模块,collection模块(python额外数据类型)

    Python进阶(十)----软件开发规范, time模块, datatime模块,random模块,collection模块(python额外数据类型) 一丶软件开发规范 六个目录: #### 对某 ...

  7. Python 爬虫十六式 - 第六式:JQuery的假兄弟-pyquery

    PyQuery:一个类似jquery的python库 学习一时爽,一直学习一直爽   Hello,大家好,我是 Connor,一个从无到有的技术小白.上一次我们说到了 BeautifulSoup 美味 ...

  8. Python 爬虫十六式 - 第七式:正则的艺术

    RE:用匹配来演绎编程的艺术 学习一时爽,一直学习一直爽   Hello,大家好,我是 Connor,一个从无到有的技术小白.上一次我们说到了 pyquery 今天我们将迎来我们数据匹配部分的最后一位 ...

  9. Python 爬虫十六式 - 第五式:BeautifulSoup-美味的汤

    BeautifulSoup 美味的汤 学习一时爽,一直学习一直爽!    Hello,大家好,我是Connor,一个从无到有的技术小白.上一次我们说到了 Xpath 的使用方法.Xpath 我觉得还是 ...

随机推荐

  1. Spring Cloud Ribbon 源码分析---负载均衡算法

    上一篇分析了Ribbon如何发送出去一个自带负载均衡效果的HTTP请求,本节就重点分析各个算法都是如何实现. 负载均衡整体是从IRule进去的: public interface IRule{ /* ...

  2. SpringMVC(十五):Dispatcher的重要组件之一MultipartResolver(StandardServletMultipartResolver和CommonsMultipartResolver)的用法

    MultipartResolver组件 从Spring官网上可以看到MultipartResolver接口的定义信息: public interface MultipartResolver A str ...

  3. Behavior Trees for Path Planning (Autonomous Driving)

    Behavior Trees for Path Planning (Autonomous Driving) 2019-11-13 08:16:52 Path planning in self-driv ...

  4. Set JAVA_HOME in windows cmd(在windows 命令行中修改JAVA_HOME)

    set JAVA_HOME=jrepathset PATH=%JAVA_HOME%\bin;%PATH%注意这里没有引号.这样就不需要在我的电脑属性中修改java_home了,以及重启命令行了.对于程 ...

  5. 解决:Could not load type 'System.ServiceModel.Activation.HttpModule' from assembly 'System.ServiceMode

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/Eric_K1m/article/deta ...

  6. java合并多个word 2007 文档 基于docx4j

    参考文章:http://dh.swzhinan.com/post/185.html 引入的jar包 <dependency> <groupId>org.docx4j</g ...

  7. jstl标签库使用报错index_jsp.java找不到问题

    初学jstl的时候记得只需要讲jstl和standard的jar放在lib下面,然后jsp中使用对应导入语法就可以使用标签库了. 但那时候用的是myeclipes,myeclipes的导包的过程记得是 ...

  8. WebGL学习笔记(十六):遮罩

    这里总结下几种WebGL中实现遮罩的方法. 模板缓冲 模板缓冲可以实现渲染剔除,但是我们之前的学习里,剔除范围是基于上一次渲染的结果,且上一次的渲染也会进行显示,这样的话并不适合用来实现遮罩. 我们想 ...

  9. Prometheus监控教程——从入门到放弃

    Prometheus的安装还是比较简单的 下载地址如下 https://prometheus.io/download/ 解压,修改配置,运行.默认监听9090端口 [root@localhost ~] ...

  10. python1-变量和简单的数据类型

    变量和简单的数据类型 1 Hello World程序 1.1 执行py文件 linux下编辑一个文件,hello.py print("Hello world") 执行 # pyth ...