抽象类,接口类,封装,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的更多相关文章

  1. 【学习笔记】--- 老男孩学Python,day18 面向对象------抽象类(接口类), 多态, 封装

    抽象类,接口类 Python没有接口这个概念 抽象类(接口类): 目的是制定一个规范 要学会归一化设计,有重复的东西就要想把它们合并起来 from abc import ABCMeta, abstra ...

  2. python面向对象 : 抽象类(接口类),多态,封装(私有制封装)

    一. 抽象类(接口类) 与java一样, python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类, 它的特殊之处在于只能被继承, 不能被实例化. 从设计角度去看, 如果类是从现实对 ...

  3. python day - 19 抽象类 接口类 多态 封装

    一. 抽象类接口类即制定一个规范 特点: 1.不可被实例化. 2.规范子类当中必须事先某个方法. 3.在python中有原生实现抽象类的方法,但没有原生实现接口类的方法. 例题:制定一个规范就是,子类 ...

  4. python 全栈开发,Day21(抽象类,接口类,多态,鸭子类型)

    一.昨日复习 派生方法和派生属性 super 只有在子父类拥有同名方法的时候, 想使用子类的对象调用父类的方法时,才使用super super在类内 : super().方法名(arg1,..) 指名 ...

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

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

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

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

  7. Python面向对象 | 抽象类和接口类

    一.抽象类(规范的编程模式) 什么是抽象类 抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化.抽象类的本质还是类,指的是一组类的相似性,而接口只强调函数属性的相似性. 为什么要有抽象类 ...

  8. 2019-03-28-day021-抽象类与接口类

    今日内容 type和class 继承 抽象类 接口类 多态 java 鸭子类型 pickle模块 collections.namedtuple type和class ##type ##class pr ...

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

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

随机推荐

  1. Win10 IIS 安装.net 4.5

    更新Win10,原来的IIS站点访问不了,原因是因为IIS 没有.net 4.5,使用网上的aspnet_regiis.exe -i命令,一点都不靠谱,直接提示: C:\WINDOWS\system3 ...

  2. POJ - 1904 King's Quest (强连通)

    题意:有N个王子,每个王子有任意个喜欢的妹子,巫师会给出一个方案:每个妹子都嫁给一个王子.但是国王希望知道:每个王子能在哪些妹子中择偶而不影响其他王子择偶. 分析:设王子为x部,妹子为y部,假设有匹配 ...

  3. Mixed mode assembly is built against version 'v2.0.50727' of the runtime and cannot be loaded in the 4.0 runtime without additional configuration info

    Mixed mode assembly is built against version 'v2.0.50727' of the runtime and cannot be loaded in the ...

  4. C# 中与等于 &= 操作符

    MSDN说,x&=y等价于 x=x&y. 整型时&运算符,进行位运算. bool类型时,&运算符,当两边结果都为ture时,结果才为true.

  5. Android 电池关机充电

    android 电池(一):锂电池基本原理篇 android 电池(二):android关机充电流程.充电画面显示 android 电池(三):android电池系统 android电池(四):电池 ...

  6. CSS3自定义发光radiobox单选框

    在线演示 本地下载

  7. NOIP 数字游戏

    描述 丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易.游戏是这样的,在你面前有一圈整数(一共n个),你要按顺序将其分为m ...

  8. Pytorch实现卷积神经网络CNN

    Pytorch是torch的Python版本,对TensorFlow造成很大的冲击,TensorFlow无疑是最流行的,但是Pytorch号称在诸多性能上要优于TensorFlow,比如在RNN的训练 ...

  9. 【原创】无线破解Aircrack-ng套件详解(一)--airmon-ng与airodump-ng

    一:Aircrack-ng详解 1.1 Aircrack-ng概述 Aircrack-ng是一款用于破解无线802.11WEP及WPA-PSK加密的工具,该工具在2005年11月之前名字是Aircra ...

  10. UNIDAC的安装

    UNIDAC的安装1.在source目录中找到对应Delphi版本目录的make.bat文件,修改其中的 set IdeDir="D:\Application\DelphiXE2指到你的de ...