一.抽象类与接口类

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. index.html(xpath素材)

    <bookstore> <title>新华书店</title> <book href="http://www.langlang2017.com/&q ...

  2. mysql 登录和退出 和简单得操作命令

    {} 是必须要有得,[]是可有,可没有得... SHOW WARNINGS (查看警告信息) SHOW CREATE DATABASE T1; (查看数据得创建sql语句)

  3. neo4j源码分析1-编译打包启动

    date: 2018-03-22 title: "neo4j源码分析1-编译打包启动" author: "邓子明" tags: - 源码 - neo4j - 大 ...

  4. RabbitMQ交换器Exchange介绍与实践

    RabbitMQ交换器Exchange介绍与实践 RabbitMQ系列文章 RabbitMQ在Ubuntu上的环境搭建 深入了解RabbitMQ工作原理及简单使用 RabbitMQ交换器Exchang ...

  5. python学习笔记(1):python基础

    python基础回顾 1.Ipython魔术命令 %timeit //多次执行一条语句,并返回平均时间,%%time->多条语句,用于测试一条语句用了多少时间 %time //返回执行一条语句的 ...

  6. 锚点定位且不改变url地址

    锚点定位且不改变url html 事件触发<li v-for="(item,index) in couponsList.swaps" :key="index&quo ...

  7. unittest加载用例

    diascover加载测试用例 1.discover方法里面有三个参数: -case_dir:这个是待执行用例的目录. -pattern:这个是匹配脚本名称的规则,test*.py意思是匹配test开 ...

  8. Spring基础13——Spring表达式语言:SpEL

    1.SpEL简介 Spring表达式语言(简称SpEL):是一个支持运行时查询和操作对象图的强大的表达式语言.语法上类似于EL:SpEL使用#{...}作为界定符,所有在大框号中的字符都将被认为是Sp ...

  9. Java设计模式之——代理设计模式

    1.什么是代理设计模式 所谓代理模式是指客户端并不直接调用实际的对象,而是通过调用代理,来间接的调用实际的对象. 这里举一个栗子:就拿我们平时租房子来举例子,好比租客和房主之间的关系,我们租房子往往不 ...

  10. ntsysv - 用于配置运行级别的简单接口

    总览 SYNOPSIS ntsysv [--back] [--level <levels>] 描述 DESCRIPTION ntsysv 是个用于配置运行级别服务(也可通过 chkconf ...