主要内容:
01 接口类
02 鸭子类型
03 多态,封装
04 类的成员(私有成员)
===============================
接口类:python中没有接口类的概念。它是为了指定一种规范
下面看一个例子:
#第一版 class Alipay: def __init__(self,money): self.money=money def pay(self): print("使用支付宝支付%s"%self.money) class Jdpay: def __int__(self,money): self.money=money def pay(self): print("使用京东支付%s"%self.money) a1=Alipay(1000) a1.pay() j1=Jdpay(500) j1.pay()
每调用一次都要用对象名.函数的方法不太好
所以改进版:
#第二版 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() a1=Alipay(1000) j1=Jdpay(10000) #归一化设计 pay(a1) pay(j1)
通过定义一个pay接口来实现归一化设计,这样既美观又实用。那要是程序员不遵循这样的归一化设计呢?,接下来介绍一种强制制定一种规范,不规范就会报错的方法:
from abc import ABCMeta,abstractmethod #强制制定一个规范,凡是继承类中必须有pay方法,如果没有,实例化对象的时候就会报错 class Payment(metaclass=ABCMeta): def __init__(self,money): delf.money=money @abstractmethod def pay(self): pass class Alipay(Payment): def pay(self): print("使用支付宝支付%s" % self.money) class Jdpay(Payment): def pay(self): print("使用京东支付%s" % self.money) class Wechatpay(Payment): def pay(self): print("使用微信支付了%s" % self.money) w1=Wechatpay(100) w1.pay() a1 = Alipay(500) a1.pay() j1=Jdpay(300) j1.pay()
第二种方式:
class Payment: """ 此类什么都不做,就是制定一个标准,谁继承我,必须定义我里面的方法。 """ def pay(self,money): raise Exception("你没有实现pay方法") class QQpay(Payment): def pay(self,money): print('使用qq支付%s元' % money) class Alipay(Payment): def pay(self,money): print('使用阿里支付%s元' % money) class Wechatpay(Payment): def fuqian(self,money): print('使用微信支付%s元' % money) def pay(obj,money): obj.pay(money) a = Alipay() b = QQpay() c = Wechatpay() pay(a,100) pay(b,200) pay(c,300) #======运行结果========= #使用阿里支付100元 # Traceback (most recent call last): # 使用qq支付200元 # File "C:/Users/HelloWorld/PycharmProjects/fullstack_s2/day 18/04 多态 封装.py", line 90, in <module> # pay(c,300) # File "C:/Users/HelloWorld/PycharmProjects/fullstack_s2/day 18/04 多态 封装.py", line 83, in pay # obj.pay(money) # File "C:/Users/HelloWorld/PycharmProjects/fullstack_s2/day 18/04 多态 封装.py", line 67, in pay # raise Exception("你没有实现pay方法") # Exception: 你没有实现pay方法
=========================
多态:同一个对象,多种形态。在python中,没有多态,或者说,都是多态...
比如我创建一个变量a=10,此时我们知道a是一个整数类型,但是我让a='jianghongwei',此时a就变成了字符串类型
这就是多态。
#在C,c++或者java中,定义变量或者给函数传值必须指定它的类型不然就会报错 int sum(int a,int b) { int c= a+b; return c; } #而在python这种弱定义类语言中,a,b是可以任意形态的 def sum(a,b): c=a+b return c
鸭子类型:在python中,你看起来像鸭子,你就是鸭子
鸭子类型是指对相同的功能取了相同的名字,这样可以方便开发,这些类型都互称鸭子类型。
比如str,tuple,list,都有index方法,这就是统一了规范
class A: def f1(self): print('In A f1...') def f2(self): print('In B f2...') class B: def f1(self): print('In B f1...') def f2(self): print('In B f2...') obj1=A() obj1.f1() obj1.f2() obj2=B() obj2.f1() obj2.f2()
======================
封装:
广义的封装:实例化一个对象,给对象空间封装一些属性
狭义的封装:私有制
私有成员:私有静态字段,私有方法,私有对象属性
class B: __money=10000 class A(B): name = 'alex' __age=1000 def func(self): print(self.__age) print(A.__age) print("func...") def func1(self): pass # print(self.__money) a1 = A() a1.func() print(a1.__age) #实例化对象不能访问私有静态字段 print(A.__age) #类名不能访问私有静态字段 #对于私有静态字段,类外部不能访问,内部可以访问
self是一个形式参数,当执行obj1=Foo('wupeiqi',18)的时候,self等于obj1.
当执行obj2=Foo('alex',73)的时候,self等于obj2
就是把内容封装到obj1和obj2的对象空间中,每个空间都有name和age
综上所述,对于面向对象的封装来说,其实就是使用构造方法将内容封装到 对象 中,然后通过对象直接或者self间接获取被封装的内容。