python面向对象 : 抽象类(接口类),多态,封装(私有制封装)
一. 抽象类(接口类)
与java一样, python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类, 它的特殊之处在于只能被继承, 不能被实例化.
从设计角度去看, 如果类是从现实对象抽象而来的, 那么抽象类就是基于类抽象而来的。
从实现角度来看, 抽象类与普通类的不同之处在于: 抽象类中有抽象方法, 该类不能被实例化, 只能被继承, 且子类必须实现抽象方法. 这一点与接口有点类似, 但其实是不同的.
实现不同的支付方式:
class Alipay:
def __init__(self, money):
self.money = money def alipay(self):
print('使用支付宝支付了%s元' % self.money) class Jdpay:
def __init__(self, money):
self.money = money def jdpay(self):
print('使用京东支付了%s元' % self.money) a = Alipay(500)
a.alipay() # 使用支付宝支付了500元
j = Jdpay(200)
j.jdpay() # 使用京东支付了200元
虽然都实现了支付,但是两个支付都是相同的功能,但调用方却不一样,可以把调用方设置一样.
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() a = Alipay(500)
pay(a) # 调用函数pay,把对象a穿进去,并执行函数语句
j = Jdpay(200)
pay(j) # 调用函数pay,把对象j穿进去,并执行函数语句
# 调用方都是函数pay 归一化设计
虽然设置了一个pay函数,但是有可能后面接手你程序的人并不会发现,含是按照第一种的方法实现新的支付方式,所以我们要确保在之后添加的类中要有pay函数.
from abc import ABCMeta, abstractmethod # 从abc模块引进ABCMeta,abstractmethod class Allpay:
@abstractmethod # 在需要制定模板的函数上写一句
def pay(self): # 制定规范,子类中必须有pay方法,否则报错
pass class Alipay(Allpay):
def __init__(self, money):
self.money = money def pay(self):
print('使用支付宝支付了%s元' % self.money) class Jdpay(Allpay):
def __init__(self, money):
self.money = money def pay(self):
print('使用京东支付了%s元' % self.money) class Wechatpay(Allpay):
def __init__(self, money):
self.money = money # def wechatpay(self): #函数名不是pay会报错
# pass
def pay(self):
print('使用微信支付了%s元' % self.money) def pay(obj):
obj.pay() a = Alipay(500)
pay(a) # 使用支付宝支付了500元
j = Jdpay(200)
pay(j) # 使用京东支付了200元
w = Wechatpay(700)
pay(w) # 使用微信支付了700元
二. 多态
python不支持多态, 也不用支持多态,因为python处处是多态, python是一种多态语言, 参数在传入之前是无法确定参数类型的. 崇尚鸭子类型
鸭子类型 : 看着像鸭子,他就是鸭子, 下面的类有相同功能的方法, 都互称为鸭子.
class Str:
def index(self):
pass class List:
def index(self):
pass class Tuple:
def index(self):
pass
三. 封装
封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容。所以,在使用面向对象的封装特性时,需要:将内容封装到某处, 然后从某处调用被封装的内容.
封装分为广义的封装和狭义的封装
广义的封装: 实例化一个对象,给对象空间封装一些属性.
class Animal:
def __init__(self,name,sex,age):
self.name = name #广义的封装
self.age = age
self.sex = sex
狭义的封装: 私有制.
私有成员 : 私有静态字段, 私有方法, 私有对象属性
私有静态字段:
在类外部引用私有静态字段
class Pay:
__money = 1000 # 定义私有静态变量__money def pay(self):
pass p = Pay()
p.__money # 报错,在类外部对象无法引用私有静态字段__money
Pay.__money # # 报错,在类外部类名无法引用私有静态字段__money
在类内部引用私有静态字段
class Pay:
__money = 1000 # 定义私有静态变量__money def pay(self):
print(p.__money) # 在类内部对象可以引用私有静态字段__money
print(Pay.__money) # 在类内部类名可以引用私有静态字段__money p = Pay()
p.pay()
#
#
在子类引用私有静态字段
class Money:
__money = 1000 # 定义私有静态变量__money class Pay(Money): def pay(self):
pass
print(p.__money) # 在子类内部对象不能引用父类的私有静态字段__money
print(Pay.__money) # 在子类内部类名不能引用父类的私有静态字段__money p = Pay()
# p.__money # 子类的对象无法引用父类的私有静态字段__money
# Pay.__money # 子类名无法引用父类的私有静态字段__money
p.pay()
总结:对于私有静态字段来说,只能在本类中内部访问,类的外部,派生类(子类)均不可访问.
# 可以访问,但是工作中千万不要用 : '__类名私有静态字段'
# print(Pay._Pay__money)
# print(Pay.__dict__)
私有方法:对于私方法来说,只能在本类中内部访问,类的外部,派生类(子类)均不可访问.
class B:
def __f1(self):
print('') class A(B):
def __func(self):
print('') def func1(self):
self.__func() # 类内部可以访问
self.f1() # 子类无法访问父类的私有方法 a = A()
# a.__func() # 类外部对象不能访问
# A.__func() # 类外部类名不能访问
a.func1()
#
#
私有属性
class A:
def __init__(self,name,age,weight):
self.name = name
self.__age = age
self.__weight = weight
def func(self):
print(self.__age) #类内可以引用私有属性
a1 = A('jsck',18,45)
print(a1.name)
print(a1.__dict__) # {'name': 'jsck', '_A__age': 18, '_A__weight': 45}
# print(a1.__age) # 类外无法引用私有属性
a1.func()
面试题
class Parent:
def __func(self):
print('in Parent func') def __init__(self): # 自动执行__init__方法
self.__func() # self.__func() =>> self.__Parent__func class Son(Parent):
def __func(self):
print('in Son func') son1 = Son() # in Parent func
python面向对象 : 抽象类(接口类),多态,封装(私有制封装)的更多相关文章
- 【学习笔记】--- 老男孩学Python,day18 面向对象------抽象类(接口类), 多态, 封装
抽象类,接口类 Python没有接口这个概念 抽象类(接口类): 目的是制定一个规范 要学会归一化设计,有重复的东西就要想把它们合并起来 from abc import ABCMeta, abstra ...
- Python面向对象之接口类(抽象类)
Python面向对象之接口类(抽象类):就是制定一个规范. 比如定义了一个接口类(抽象类)(他们是不可以进行实例化的,这就是他为什么是制定一个规范的原因). 他的定义是需要abc模块,要变的就是他的方 ...
- python day - 19 抽象类 接口类 多态 封装
一. 抽象类接口类即制定一个规范 特点: 1.不可被实例化. 2.规范子类当中必须事先某个方法. 3.在python中有原生实现抽象类的方法,但没有原生实现接口类的方法. 例题:制定一个规范就是,子类 ...
- python 全栈开发,Day21(抽象类,接口类,多态,鸭子类型)
一.昨日复习 派生方法和派生属性 super 只有在子父类拥有同名方法的时候, 想使用子类的对象调用父类的方法时,才使用super super在类内 : super().方法名(arg1,..) 指名 ...
- python笔记5 接口类抽象类 封装 反射 设计模式 模块 :random随机数 josn shelve持久化存储
接口类抽象类 接口类:接口类就是制定一个规则,让其他人按照我的规则去写程序. #!/usr/bin/env python from abc import ABCMeta,abstractmethod ...
- Python面向对象 | 抽象类和接口类
一.抽象类(规范的编程模式) 什么是抽象类 抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化.抽象类的本质还是类,指的是一组类的相似性,而接口只强调函数属性的相似性. 为什么要有抽象类 ...
- Python面向对象初始(三大特征,多态,继承,封装)
Python面向对象的初始 面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西. 优点是:极大的降低了写程序的 ...
- Python 面向对象编程 继承 和多态
Python 面向对象编程 继承 和多态 一:多继承性 对于java我们熟悉的是一个类只能继承一个父类:但是对于C++ 一个子类可以有多个父亲,同样对于 Python一个类也可以有多个父亲 格式: c ...
- Python面向对象06 /元类type、反射、函数与类的区别、特殊的双下方法
Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 目录 Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 1. 元类type 2. 反射 3 ...
随机推荐
- 有关O_APPEND标志和lseek()的使用
编程之路刚刚开始,错误难免,希望大家能够指出. O_APPEND表示以每次写操作都写入文件的末尾.lseek()可以调整文件读写位置. <<Linux/UNIX系统编程手册>> ...
- window.location.herf=url参数有中文,到后台乱码问题解决
js中的代码: /*将中文的参数进行两次编码 */ function queryByName(){ //获取查询条件的用户名 ...
- react 简书开发笔记
详见文章<React简书开发实战课程笔记>
- set集合的遍历(基于迭代器和增强for循环,没有一般的for循环)
赋:开发项目中见到的代码 Java中Set集合是一个不包含重复元素的Collection,首先我们先看看遍历方法 package com.sort; import java.util.HashSet; ...
- 【转存】Vue组件选项props
原帖地址 前面的话 组件接受的选项大部分与Vue实例一样,而选项props是组件中非常重要的一个选项.在 Vue 中,父子组件的关系可以总结为 props down, events up.父组件通过 ...
- express 与 koa 区别
express 与 koa 区别 区别项 express koa 中间件模型 Compress 模型 洋葱圈模型 对象个数 只有2个对象:Request 和 Response 有3个对象:Reques ...
- OpenGL纹理
如果不用头文件,把所有东西堆在同一个cpp文件中,会出现“超出GPU内存的错误!” 1 //我们自己的着色器类 #ifndef SHADER_H #define SHADER_H #include & ...
- 读DataSnap源代码(一)
Delphi的DataSnap用了一段时间了,但一直感觉有些地方还不够了解,所以花时间阅读了源代码,特作此烂笔头. Datasnap是在之前的WebBorker基础上搭建的,DataSnap向导自动生 ...
- 【转】解决ubuntu13.10下,无法双击运行脚本文件
解决ubuntu13.10下,无法双击运行脚本文件 转自:http://www.aichengxu.com/other/975350.htm 首先,必须先设定好脚本的运行方法,当然如果只是she ...
- Spring Cloud(Dalston.SR5)--Eureka 注册中心高可用-服务提供和消费
由于 Eureka 注册中心只是在内存中保存服务注册实例,并且没有将服务注册实例进行同步,因此我们需要对服务提供和消费进行调整,需要指定服务提供和消费的注册.服务发现的具体Eureka 注册中心配置, ...