主要内容:
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): passclass 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# 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=10000class 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间接获取被封装的内容。