抽象类,接口类,封装,property,classmetod,statimethod
抽象类,接口类,封装,property,classmetod,statimethod(类方法,静态方法)
一丶抽象类和接口类
接口类(不崇尚用)
接口类:是规范子类的一个模板,只要接口类中定义的,就应该在子类中实现
接口类不能被实例化,只能被继承
支持多继承,父类不实现
python 本身支持多继承,没有接口专用的语法。但是得知道接口的概念
例子:
class Alipay:
'''
支付宝支付
'''
def pay(self,money):
print('支付宝支付了%s元'%money) class Applepay:
'''
apple pay支付
'''
def pay(self,money):
print('apple pay支付了%s元'%money) class Wechatpay:
def fuqian(self,money):
'''
实现了pay的功能,但是名字不一样
'''
print('微信支付了%s元'%money) def pay(payment,money):
'''
支付函数,总体负责支付
对应支付的对象和要支付的金额
'''
payment.pay(money) p = Wechatpay()
pay(p,200) #执行会报错
第一种解决方式(比较low)
class Payment:
def pay(self):
raise NotImplementedError class Wechatpay(Payment):
def fuqian(self,money):
print('微信支付了%s元'%money) p = Wechatpay() #这里不报错
pay(p,200) #这里报错了
第二种(高级方式)
from abc import ABCMeta,abstractmethod
# 接口类:
# 是规范子类的一个模板,
# 只要接口类中定义的,就应该在子类中实现(规范所有支付功能必须实现pay方法)
# 接口类不能被实例化,它只能被继承
# 支持多继承
class Payment(metaclass=ABCMeta): #模板,接口类
@abstractmethod #装饰接口类中方法的,加上这个装饰器,自动检测子类中的方法名
def pay(self,money):pass @abstractmethod
def get(self):pass # 收钱功能 class Apple_Pay(Payment):
def pay(self,money):
print('您使用苹果支付支付了%s元'%money) class Ali_Pay(Payment):
def pay(self, money):
print('您使用支付宝支付了%s元' % money) class WeChat_Pay(Payment):
def pay(self,money):
print('您使用微信支付了%s元' % money) def pay(obj,money):
return obj.pay(money)
#接口类 : 多继承,父类不实现
from abc import ABCMeta,abstractmethod
class Fly_Animal(metaclass=ABCMeta): #规范
@abstractmethod
def fly(self):pass class Swim_Animal(metaclass=ABCMeta):
@abstractmethod
def swim(self): pass class Walk_Animal(metaclass=ABCMeta):
@abstractmethod
def walk(self): pass class Frog(Walk_Animal,Swim_Animal):
def walk(self):
print('自己实现walk功能') def swim(self): pass class Swan(Walk_Animal,Swim_Animal,Fly_Animal):
pass class Bird(Walk_Animal,Fly_Animal):
pass
接口隔离原则: 使用多个专门的接口,而不使用单一的总接口。即客户端不应该依赖那些不需要的接口。
抽象类
抽象类可以实现一些子类共有的功能和属性\抽象类不鼓励多继承
python 没有接口的概念
只能借助抽象类的模块 来实现接口类
接口 —— java : 没有多继承 —— Interface
from abc import ABCMeta,abstractmethod
class Base(metaclass=ABCMeta):
def __init__(self,filename):
self.filename = filename
@abstractmethod #抽象方法
def open(self):
return 'file_handler' @abstractmethod
def close(self):pass @abstractmethod
def read(self):pass @abstractmethod
def write(self):pass class File(Base):
def open(self):pass
def close(self):pass
def read(self):pass
def write(self):pass # 抽象类不能被实例化
# 这个抽象类可以规范子类必须实现抽象类中的抽象方法
二、封装(重要)
封装: 隐藏对象的属性和实现细节,仅对外提供公共访问方式
把一些属性和方法放到类里 这本身就是一种封装(广义上的封装)
面对对象里的封装 : 把属性和方法藏在类里 我只能在类内部调用,不能再外部使用(实际意义)
好处:
1. 将变化隔离; 2. 便于使用;3. 提高复用性; 4. 提高安全性;
原则:
1. 将不需要对外提供的内容都隐藏起来;
2. 把属性都隐藏,提供公共方法对其访问。
加__藏起来
class Dog:
__role = 'dog' # 私有的静态属性,在语法上是可以把类的数据属性设置成私有的如__N,会变形为_Dog__N
def func(self): # 内部使用
print(Dog.__role) # _Dog__role 私有方法
# print(Dog.role)
print(Dog.__dict__) # 查看名字空间
print(Dog._Dog__role)# 不鼓励这样调用私有变量 dog 查私有静态属性
从类的外面不能直接调用,在类内的使用加上了一层密码:_类名 d = Dog() #能实例化
d.func()
私有动态方法
class Dog:
__role = 'dog' # 私有的静态属性
def __discount(self):
print('in __func') # 私有方法 (动态) def price(self):
self.__discount() print(Dog.__dict__)
print(Dog._Dog__discount)
定义一个私有变量\属性\方法:__名字
在类的内部可以直接使用: __名字
在类的外部不能直接使用,如果一定要用,在私有方法之前加上:_类名,变成_类名__名字 # 不推荐使用
在类外的名字 通过__dict__就可以查看
私有的
私有的静态属性、方法、对象属性
使用__名字的方式调用,保证在类内部可以调用,外部不行 class Room:
def __init__(self,name,price,length,width):
self.name = name
self.price = print
self.__length = length # 私有的对象属性
self.__width = width def area(self):
return self.__length*self.__width house = Room('天空之镜',100000,200,1)
print(house.area())
私有属性能否被继承: 不能
私有的 不能被继承
当有一个名字,不想被外部使用也不想被子类继承,只想内部使用的时候就定义私有的
class A:
def __func(self):
print('__a_func') _A__func class B(A):
def __init__(self):
self.__func() _B__func b= B() # 报错
三、property内置(会使代码变整洁)
property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值
例子:1、
@property 把一个方法 伪装成一个属性
1 属性的值 是这个方法的返回值
2 这个方法不能有参数
class Person:
def __init__(self,name,height,weight):
self.name = name
self.height = height
self.weight = weight # @property 加了方法变属性
def bmi(self): #bmi人的一个属性
self.weight/(self.height ** 2) li = Person('lishi',1.65,50)
print(li.bmi) # 属性
print(li.bmi()) # 方法
2、
圆形类
from math import pi
class Circle:
def __init__(self, r):
self.radius = r @property
def perimeter(self):
return 2 * pi * self.radius @property
def area(self):
return pi * (self.radius ** 2) c1 = Circle(5)
print(c1.area)
class Goods:
discount = 0.8 # 静态属性
def __init__(self,name,price):
self.name = name
self.__price = price # 原价 @property
def price(self): # 折后价
return self.__price * Goods.discount apple = Goods('榴莲',10)
print(apple.price) # 8.0
banana = Goods('香蕉',2.5)
print(banana.price) 2.0 apple.price = 6 # 修改不了原价
print(apple.price) # 报错
解决:setter
class Goods:
discount = 0.8 # 静态属性 全部打8折
def __init__(self,name,price):
self.name = name
self.__price = price # 原价 @property
def price(self): # 折后价
return self.__price * Goods.discount @price.setter # 加红的名字必须一样的才会有效果
def price(self,new_price): # 修改原价
# if type(new_price) is int: # 加了,可以增加安全性,使用setter的优势
self.__price = new_price
# self.__price = new_price
apple = Goods('苹果',20) # 原价
apple.price = 10 # 修改原价(只能传一个参数) setter
print(apple.price) # property
封装
__私有+property
让对象的属性变得更安全了
获取到的对象的值可以进行一些加工
修改对象的值的同时可以进行一些验证 setter
一个静态属性property本质就是实现了get,set,delete三种方法
class Foo:
@property # 把AAA伪装成一个属性
def AAA(self):
print('get的时候运行我啊') @AAA.setter # 修改值
def AAA(self,value):
print('set的时候运行我啊') @AAA.deleter # 删除
def AAA(self):
print('delete的时候运行我啊') #只有在属性AAA定义property后才能定义AAA.setter,AAA.deleter
f1=Foo()
f1.AAA
f1.AAA='aaa'
del f1.AAA
class Foo:
def get_AAA(self):
print('get的时候运行我啊') def set_AAA(self,value):
print('set的时候运行我啊') def delete_AAA(self):
print('delete的时候运行我啊')
AAA=property(get_AAA,set_AAA,delete_AAA) #内置property三个参数与get,set,delete一一对应 f1=Foo()
f1.AAA
f1.AAA='aaa'
del f1.AAA
使用:
class Goods:
__discount = 0.8 #静态属性
def __init__(self,name,price):
self.__name = name
self.__price = price #原价
@property
def name(self):
return self.__name @name.setter
def name(self,new_name):
self.__name = new_name @name.deleter
def name(self):
del self.__name @property
def price(self): #折后价
return self.__price * Goods.__discount @price.setter
def price(self,new_price): #修改原价
if type(new_price) is int:
self.__price = new_price apple = Goods('苹果',10)
del apple.name
print(apple.name) # 报错,已删除
四、classmethod和staticmthod(类方法、静态方法)
问题:定义一个类类里面的方法并没有用到self
例如:
# 与apple无关,所以def change_discount(self,new_discount)在这里不适合
# 需实例化
class Goods:
__discount = 0.8
def change_discount(self,new_discount):
Goods.__discount = new_discount
apple = Goods() # 实例化
apple.change_discount(0.75)
修改版
类方法:
class Goods:
__discount = 0.8
@classmethod #类方法
def change_discount(cls,new_discount):
cls.__discount = new_discount
@classmethod
def get_discount(cls):
return cls.__discount
# apple = Goods()
Goods.change_discount(0.75)
print(Goods.get_discount())
类方法好处:
调用:不需要实例化 直接用类名调用就好
定义:不用接受self参数,默认传cls,cls就代表当前方法所在的类
什么时候用类方法?
需要使用静态变量 且 不需要和对象相关的任何操作的时候
静态方法:
如果这个方法 既不需要操作静态变量也不需要使用对象相关的操作,就使用静态方法
class A:
@staticmethod
def func(name): #静态方法
print(123)
A.func('alex')
class A:
@staticmethod
def func(): #静态方法
print(123)
A.func()
面向对象编程:专门为面向对象编程提供的一个方法——staticmethod
它完全可以当做普通函数去用,只不过这个函数要通过类名.函数名调用
其他 传参 返回值 完全没有区别 类里面,一共可以定义这三种方法:
普通方法 self
类方法 cls @classmrthod
静态方法 @staticmethod
绑定方法 和 非绑定方法 class A:
@staticmethod
def func1(name): #静态方法
print(123) @classmethod
def func2(cls): # 静态方法
print(123) def func3(self):pass
a = A()
print(a.func1) #静态方法
print(a.func2) #类方法 : 绑定到A类的func
print(a.func3) #普通方法:绑定到A类对象的func
静态方法和类方法 都是直接可以使用类名调用
普通方法:对象调用
类能解决的事,没必要搞个实例化对象能弄
抽象类,接口类,封装,property,classmetod,statimethod的更多相关文章
- 【学习笔记】--- 老男孩学Python,day18 面向对象------抽象类(接口类), 多态, 封装
抽象类,接口类 Python没有接口这个概念 抽象类(接口类): 目的是制定一个规范 要学会归一化设计,有重复的东西就要想把它们合并起来 from abc import ABCMeta, abstra ...
- python面向对象 : 抽象类(接口类),多态,封装(私有制封装)
一. 抽象类(接口类) 与java一样, python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类, 它的特殊之处在于只能被继承, 不能被实例化. 从设计角度去看, 如果类是从现实对 ...
- 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's twenty-first day for me 抽象类和接口类以及多态
归一化设计: 不管是哪一个类的对象,都调用同一个函数去完成相似的功能. class Alipay: def pay(self,money): print('使用支付宝支付了%s' % money) c ...
- Python面向对象 | 抽象类和接口类
一.抽象类(规范的编程模式) 什么是抽象类 抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化.抽象类的本质还是类,指的是一组类的相似性,而接口只强调函数属性的相似性. 为什么要有抽象类 ...
- 2019-03-28-day021-抽象类与接口类
今日内容 type和class 继承 抽象类 接口类 多态 java 鸭子类型 pickle模块 collections.namedtuple type和class ##type ##class pr ...
- python学习之老男孩python全栈第九期_day025知识点总结——接口类、抽象类、多态、封装
一. 接口类 java:面向对象编程 设计模式 -- 接口类 接口类:python原生不支持 抽象类:python 原生支持的 from abc import abstractclassmethod, ...
随机推荐
- (转载)Hibernate与Jpa的关系
我知道Jpa是一种规范,而Hibernate是它的一种实现.除了Hibernate,还有EclipseLink(曾经的toplink),OpenJPA等可供选择,所以使用Jpa的一个好处是,可以更换实 ...
- 【转】PCA与Whitening
PCA: PCA的具有2个功能,一是维数约简(可以加快算法的训练速度,减小内存消耗等),一是数据的可视化. PCA并不是线性回归,因为线性回归是保证得到的函数是y值方面误差最小,而PCA是保证得到的函 ...
- JMeter接口测试和压力测试
JMeter接口测试和压力测试 JMeter可以做接口测试和压力测试.其中接口测试的简单操作包括做http脚本(发get/post请求.加cookie.加header.加权限认证.上传文件).做web ...
- 异步消息postEvent更新界面
其实就是和Qt::QueuedConnection时的信号槽一样,属于异步的. 1.新建QEvent子类 ①.头文件 #ifndef MYEVENT_H #define MYEVENT_H #incl ...
- Javascript -- 示例:多选下拉选框
1. 示例:多选下拉选框 <html> <head> <meta http-equiv="Content-Type" content="te ...
- gitlab 备份
gitlab 备份 gitlab-rake gitlab:backup:create 执行之后,就会生成一个备份文件 [root@iZuf6dztc469onegfborf5Z backups]# l ...
- Spring Boot的核心
1.1.1. 入口类和@SpringBootApplication Spring Boot的项目一般都会有*Application的入口类,入口类中会有main方法,这是一个标准的Java应用程序 ...
- Spring中Bean的生命周期是怎样的
1.Spring对Bean进行实例化(相当于程序中的new Xx()) 2.Spring将值和Bean的引用注入进Bean对应的属性中 3.如果Bean实现了BeanNameAware接口,Sprin ...
- 测绘类SCI
GeoInformatica(国际地理信息系统计算机科学进展杂志)美国International Journal of Geographical Information Science(国际地理信息科 ...
- 2012 Multi-University Training Contest 7
2012 Multi-University Training Contest 7 A.As long as Binbin loves Sangsang B.Dead or alive C.Dragon ...