接口类
接口类:是规范子类的一个模板,只要接口类中定义的,就应该在子类中实现
接口类不能被实例化,它只能被继承
支持多继承
接口隔离原则:使用多个专门的接口,而不使用单一的总接口。即客户端不应该依赖那些不需要的接口
from abc import ABCMeta,abstractmethod
class Payment(metaclass=ABCMeta): # 元类 模板,接口类 @abstractmethod # 装饰接口类中方法的,加上了这个装饰器,自动检测子类中的方法名 def pay(self,money):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) apple = Apple_Pay() ali = Ali_Pay() wechat = WeChat_Pay()
抽象类
模板 规范
抽象类可以实现一些子类共有的功能和属性
抽象类不鼓励多继承
文件操作:打开文件 关闭文件 写文件 读文件
硬盘操作: 打开 关闭 写 读
进程文件: 打开 关闭 写 读
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
封装
class Dog: __role = 'dog' # 私有静态属性 # def func(self): # print(Dog.__role) def __func(self): print('in__func') # print(Dog.__role) # 报错 print(Dog.__dict__) # '_Dog__role': 'dog' print(Dog._Dog__role) # dog 从类的外面不能直接调用,在类外的使用加上了一层密码:_类名 d = Dog() # d.func() # dog d._Dog__func() # in__func
定义一个私有变量属性方法: __名字
在类的内部直接使用: __名字
在类的外部不能直接使用,如果一定要用,在私有方法之前加上: __类名,变成 _类名__名字
在类外的名字 通过__dict__查看
class Room: def __init__(self,name,price,length,width): self.name = name self.price = price self.__length = length # 私有的对象属性 self.__width = width def area(self): return self.__length*self.__width house = Room('房子',1000000,2,1) print(house.area())
私有的
私有的静态属性、方法、对象属性
使用__名的方式调用,保证在类内部可以调用,外部不行
私有的 不能被继承
当有一个名字,不想被外部使用也不想被子类继承,只想在内部使用的时候就定义私有的
class Person: def __init__(self,name,height,weight): self.name = name self.height = height self.weight = weight @property def bmi(self): return self.weight / (self.height**2) li = Person('李岩',1.75,85) print(li.bmi)
@property 把一个方法伪装成一个属性
1.属性的值 是这个方法的返回值
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.perimeter) 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 @price.setter def price(self,new_price): # 修改原价 if type(new_price) is int: self.__price = new_price apple = Goods('苹果',10) apple.kind = '富士' apple.price = 6 print(apple.price)
封装
__私有+property
让对象的属性变得更安全了
获取到的对象的值可以进行一些加工
修改对象的值的同时可以进行一些验证
伪装后属性的修改和删除
class Foo: @property 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
classmethod和staticmethod
类方法
调用:不需要实例化 直接用类名调用就好
定义:不用接收self参数,默认传cls,cls就代表当前方法所在的类
什么时候用类方法
需要使用静态变量且不需要和对象相关的任何操作的时候
class Goods: __discount = 0.8 @classmethod # 类方法 def change_discount(cls,new_discount): cls.__discount = new_discount @classmethod def get_discount(cls): return cls.__discount Goods.change_discount(0.75) print(Goods.get_discount())
静态方法
如果这个方法既不需要操作静态变量也不需要使用对象相关的操作,就使用静态方法
class A: @staticmethod def func(): print(123)
面向对象编程: 专门为面向对象编程提供的一个方法——staticmethod
它完全可以当作普通的函数去用,只不过这个函数要通过类名.函数名()调用
其他 传参 返回值 完全没有区别
类里面:一共可以定义三种方法
普通方法 self
类方法 cls
静态方法
绑定方法和非绑定方法
class A: @staticmethod def func1(): print(123) @classmethod def func2(cls): print(123) def func3(self):pass a = A() print(a.func1) # 静态方法 <function A.func1 at 0x000000000236AA60> print(a.func2) # 类方法 <bound method A.func2 of <class '__main__.A'>> 绑定到A类的func print(a.func3) # 普通方法 <bound method A.func3 of <__main__.A object at 0x000000000236B668>> 绑定到A类对象的func
静态方法和类方法 都是直接可以使用类名调用
普通方法:对象调用