一.抽象类与接口类

1.抽象类:抽象即类似或者说比较像的部分,继承描述的是父类与子类的一种关系,要找出这种关系,必须先抽象再继承;

a:抽象分成两个层次:

  1)由对象->类:将两个有相似地方的对象抽取成类;

  2)由类->父类:将两个有相似地方的类抽取成父类;

:抽象最主要的作用就是划分类别(可以隔离关注点,降低复杂度)

2.为什么要有抽象类

与Java一样,Python也有抽象类的概念,需要借助模块实现,它是一个特殊的类,特殊之处在于只能被继承,不能被实例化;

  类是从一些对象中抽取相同的内容而来的,那如果类中有相似的地方,就引出了抽象类概念,

  所以从实现的角度来看,抽象类与普通类的不同之处在于:抽象类只能有抽象方法(没有实现功能),这个类不能被实例化,只能被继承,且子类必须实现抽象方法;

 #用代码来表示一下接口类和抽象类:

 #版本一
class Alipay:
def __init__(self,money):
self.money = money
def pay(self):
print('阿里支付了%s元!' % self.money)
class Jdpay:
def __init__(self,money):
self.money = money
def pay(self):
print('京东支付了%s元!' % self.money)
p1 = Alipay(1000)
p1.pay() #这里是Alipay.pay()
p2 = Jdpay(1000)
p2.pay() #这里是Jdpay.pay()
#输出结果:
阿里支付了1000元!
京东支付了1000元!

#虽然你调用pay方法格式没有错,但是不合理,工作中如果有人接着你的程序写一个微信支付,它写的格式和你的可能就不一样,不能体现归一化的设计理念;

2)所以引出第二版(接口的概念)

a:接口提取了一群类共同的函数,可以把接口当做一个函数的集合,然后让子类去实现接口中的函数

这么做的意义在于归一化,归一化就是只要基于同一个接口实现的类,那么所有的这些类产生的对象在使用时,

从用法上来说都一样;

归一化的好处在于:

1. 归一化让使用者无需关心对象的类是什么,只需要的知道这些对象都具备某些功能就可以了,这极大地降低了使用者的使用难度。

2. 归一化使得高层的外部使用者可以不加区分的处理所有接口兼容的对象集合

代码展示:

 #版本二
class Alipay:
def __init__(self,money):
self.money = money
def pay(self):
print('阿里支付了%s元!' % self.money)
class Jdpay:
def __init__(self,money):
self.money = money
def pay(self):
print('京东支付了%s元!' % self.money)
def pay(obj): #接口函数(约定俗成,内行程序员大家都看的懂)
obj.pay()
p1 = Alipay(1000)
pay(p1)
p2 = Jdpay(1000)
pay(p2)
#输出结果:
阿里支付了1000元!
京东支付了1000元!

**这种做法相对于有素质的程序员行,但是万一来个野生程序员,还按版本一的方式写,就又乱套了;

所以引出第三种写法:抽象类(类似于接口)起规范化作用:

 class Pay(metaclass=ABCMeta):
all_type = 'alex'
@abstractmethod #每一个子类中都要有这个方法,定义格式
def pay(self):pass #规范一个方法上面加一句@abstractmethod
class Alipay(Pay):
def __init__(self,money):
self.money = money
def pay(self):
print('阿里支付了%s元!' % self.money)
class Jdpay(Pay):
def __init__(self,money):
self.money = money
def pay(self):
print('京东支付了%s元!' % self.money)
class Wxpay(Pay):
def __init__(self,money):
self.money = money
def wupay(self): #这里没有pay方法,再实例化对象时会报错
pass
p1 = Wxpay(200)
#输出结果:
TypeError: Can't instantiate abstract class Wxpay with abstract methods pay

二.多态

1.多态概念:多态就是一个对象有多种状态,例如文件有可执行文件和文本文件;

2.多态性:这是指在不考虑实例类型的情况下使用实例

就比如:老师,下课铃响了(),学生,下课铃响了(),老师执行的是下班操作,学生执行的是方向操作,
虽然二者消息一样,但是执行的效果不同;

3.多态的好处:a:增加了程序的灵活性  b:增加了程序的可扩展性

4.鸭子类型:Python崇尚鸭子类型,即"如果看起来像,叫声而且走路像鸭子,那么它就是鸭子",其实Python中没有多态的概念,因为它处处都是多态,不用考虑数据类型,传入函数,封装到对象都可以.

举例1:你只要像鸭子,我就可以用鸭子的方法或属性对你使用;

  利用标准库中定义的各种‘与文件类似’的对象,尽管这些对象的工作方式像文件,但他们没有继承内置文件对象的方法

#二者都像鸭子,二者看起来都像文件,因而就可以当文件一样去用
class TxtFile:
def read(self):
pass def write(self):
pass class DiskFile:
def read(self):
pass
def write(self):
pass

例2:其实大家一直在享受着多态性带来的好处,比如Python的序列类型有多种形态:字符串,列表,元组,多态性体现如下:

#str,list,tuple都是序列类型
s=str('hello')
l=list([1,2,3])
t=tuple((4,5,6)) #我们可以在不考虑三者类型的前提下使用s,l,t
s.__len__()
l.__len__()
t.__len__() len(s)
len(l)
len(t)

三.封装

1. a:广义的封装:

  实例化一个对象,给对象空间封装一些属性;

  b:狭义的封装:私有制,私有静态字段,私有方法,私有对象属性;

    格式为__变量名或则__方法名

2.私有封装的特点

  a:实例化的对象不能在外访问私有静态字段;

  b:类名在外不能访问静态字段;  所以对于私有静态字段,类的外部和派生类都不能访问;

  c:对于私有静态字段来说,只有在本类内部方法或属性中可以访问

3.讲解在定义私有封装属性是Python内部机制

  在Python中用双下划线开头的方式将属性隐藏了起来(设置成私有的)

#其实这仅仅这是一种变形操作且仅仅只在类定义阶段发生变形
#类中所有双下划线开头的名称如__x都会在类定义时自动变形成:_类名__x的形式: class A:
__N=0 #类的数据属性就应该是共享的,但是语法上是可以把类的数据属性设置成私有的如__N,会变形为_A__N
def __init__(self):
self.__X=10 #变形为self._A__X
def __foo(self): #变形为_A__foo
print('from A')
def bar(self):
self.__foo() #只有在类内部才可以通过__foo的形式访问到.
#A._A__N是可以访问到的,
#这种,在外部是无法通过__x这个名字访问到。

所以在函数外部,你若想要访问函数私有变量或方法,只需要在前面加上_类名__方法名()即可;

4.封装的意义

1).封装数据:将数据隐藏起来这不是目的,隐藏起来后对外提供接口时,我们可以直接在接口上对该数据操作做出限制,以此完成对数据属性操作的严格控制;

class Teacher:
def __init__(self,name,age):
# self.__name=name
# self.__age=age
self.set_info(name,age) def tell_info(self):
print('姓名:%s,年龄:%s' %(self.__name,self.__age))
def set_info(self,name,age):
if not isinstance(name,str):
raise TypeError('姓名必须是字符串类型')
if not isinstance(age,int):
raise TypeError('年龄必须是整型')
self.__name=name
self.__age=age t=Teacher('egon',18)
t.tell_info() t.set_info('egon',19)
t.tell_info()

2).封装方法:不能直接调用我的方法,你只能看到一个最终的接口

封装方法举例:

1. 你的身体没有一处不体现着封装的概念:你的身体把膀胱尿道等等这些尿的功能隐藏了起来,然后为你提供一个尿的接口就可以了(接口就是你的。。。,),你总不能把膀胱挂在身体外面,上厕所的时候就跟别人炫耀:hi,man,你瞅我的膀胱,看看我是怎么尿的。

2. 电视机本身是一个黑盒子,隐藏了所有细节,但是一定会对外提供了一堆按钮,这些按钮也正是接口的概念,所以说,封装并不是单纯意义的隐藏!!!

3. 快门就是傻瓜相机为傻瓜们提供的方法,该方法将内部复杂的照相功能都隐藏起来了

提示:在编程语言里,对外提供的接口(接口可理解为了一个入口),可以是函数,称为接口函数,这与接口的概念还不一样,接口代表一组接口函数的集合体。

#取款是功能,而这个功能有很多功能组成:插卡、密码认证、输入金额、打印账单、取钱
#对使用者来说,只需要知道取款这个功能即可,其余功能我们都可以隐藏起来,很明显这么做
#隔离了复杂度,同时也提升了安全性 class ATM:
def __card(self):
print('插卡')
def __auth(self):
print('用户认证')
def __input(self):
print('输入取款金额')
def __print_bill(self):
print('打印账单')
def __take_money(self):
print('取款') def withdraw(self):
self.__card()
self.__auth()
self.__input()
self.__print_bill()
self.__take_money() a=ATM()
a.withdraw()

Python_015(面向对象(接口类,抽象类,多态,封装)的更多相关文章

  1. python开发面向对象基础:接口类&抽象类&多态&钻石继承

    一,接口类 继承有两种用途: 一:继承基类的方法,并且做出自己的改变或者扩展(代码重用) 二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口名(就是函数名)且并未实 ...

  2. day27 多态 多继承 接口类 抽象类

    简单来说:多态就是指一个相同的方法名在不同的对象调用的时候实现一样或者不一样的方法实例1: 动物类有个方法 "嚎叫" 狗类也有个方法 "嚎叫" 猫类继承了动物类 ...

  3. python笔记5 接口类抽象类 封装 反射 设计模式 模块 :random随机数 josn shelve持久化存储

    接口类抽象类 接口类:接口类就是制定一个规则,让其他人按照我的规则去写程序. #!/usr/bin/env python from abc import ABCMeta,abstractmethod ...

  4. Python进阶-XVII 非python的接口类、多态、python自己的封装

    1.python模拟java中的接口类 python中是没有接口类的概念的,因为它支持多继承,但是java不能,所以就提出一个接口类的概念 java : 面向对象编程 设计模式 —— 接口 接口类 : ...

  5. 日历类和日期类转换 并发修改异常 泛型的好处 *各种排序 成员和局部变量 接口和抽象类 多态 new对象内存中的变化

    day07 ==和equals的区别? ==用于比较两个数值 或者地址值是否相同.  equals 用于比较两个对象的内容是否相同   String,StringBuffer.StringBuilde ...

  6. python's twenty-first day for me 抽象类和接口类以及多态

    归一化设计: 不管是哪一个类的对象,都调用同一个函数去完成相似的功能. class Alipay: def pay(self,money): print('使用支付宝支付了%s' % money) c ...

  7. php中普通类 接口类 抽象类 浅谈

    一.普通类 1.关键词:class  类名,继承关键字extends 2.继承:只能实现单继承, 3.多态:子类继承可以实现多种功能 4.封装:类有权限机制,私有的只能自己用,受保护的可以被继承,子类 ...

  8. python学习之老男孩python全栈第九期_day025知识点总结——接口类、抽象类、多态、封装

    一. 接口类 java:面向对象编程 设计模式 -- 接口类 接口类:python原生不支持 抽象类:python 原生支持的 from abc import abstractclassmethod, ...

  9. day 25-1 接口类、抽象类、多态

    # 接口类:python 原生不支持# 抽象类:python 原生支持的 接口类 首先我们来看一个支付接口的简单例子 from abc import abstractmethod,ABCMeta #我 ...

随机推荐

  1. LeetCode.860-卖柠檬水找零(Lemonade Change)

    这是悦乐书的第331次更新,第355篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第201题(顺位题号是860).在柠檬水摊上,每杯柠檬水的价格为5美元.客户站在队列中向 ...

  2. Grass Planting

    大致题意: 维护一棵树,支持两种操作: P x y x到y路径上的每条边的值+1:Q x y 询问x到y路径上所有边的值的和.Input第一行两个正整数,N,M表示点数和操作数:接下来N-1行每行两个 ...

  3. PIL实现图片框架以及生成图片验证码

    1. PIL的基本概念 PIL:即Python Imaging Library,是Python平台事实上的图像处理标准库. PIL中涉及通道(bands)和模式(mode)这两个重要概念. (1)通道 ...

  4. 【Qt开发】【Linux开发】Qt程序在嵌入式设备(arm) 上运行,鼠标擦除界面的解决方案

    笔者最近想在arm开发板上,开发一个应用程序,经过网上查询发现qt作为跨平台开发软件很不错,于是便选择了qt开发,笔者的qt版本是4.8.6的.由于arm的主频太低,在arm上进行开发编译,效率会大大 ...

  5. Canvas入门05-渐变颜色

    线性渐变API: ctx.createLinearGradient(double x1, double y1, double x2, double y2) 创建一个渐变实例 (x1, y1) 渐变的起 ...

  6. Quartz-第四篇 常规quartz的使用

    1.目录结构 2.主要文件 1>引入的jar包,quartz-2.2.2解压后lib下所有的jar包 2>quartz.properties org.quartz.threadPool.t ...

  7. 块设备驱动——ramblock

    一. 什么是块设备. 1.1. 一种具有一定结构的随机存取设备,对这种设备的读写是按块进行的,他使用缓冲区来存放暂时的数据,待条件成熟后,从缓存一次性写入设备或者从设备一次性读到缓冲区.可以随机访问, ...

  8. 6-2 如何读写json数据

    通过查看help(json.dump)和help(json.dumps)帮助信息,dump是将转换格式到文件对象,而dumps转换格式到字符串. 一.Json.dumps() Json.dumps() ...

  9. mongodb启动报错,child process failed, exited with error number 1

    error: child process failed, exited with error number 1 第一次安装mongodb,随后启动一般不会出现上面的错误,出现这种错误的原因一般是mon ...

  10. scala学习笔记(7)

    1.包 --------------------------------------- Scala中的包和Java或者C++中命名空间的目的是相同的:管理大型程序中的名称. package a{ pa ...