一.抽象类,接口类
1.抽象类,接口类:制定一个规范
from abc import ABCMeta, abstractmethod
class Payment(metaclass=ABCMeta): # 抽象类, 接口类,规范和约束,mataclass指定的是一个元类
@abstractmethod
def pay(self): # 抽象一个pay方法,继承Payment类的子类必须有此方法,否则实例化时会报错
pass
class Alipay(Payment):
def __init__(self, money):
self.money = money
def pay(self):
print("使用支付宝支付了%s" % self.money)
class Qqpay(Payment):
def __init__(self, money):
self.money = money
def pay(self):
print("使用qq支付了%s" % self.money)
class Wechatpay(Payment):
def __init__(self, money):
self.money = money
def pay(self):
print("使用微信支付了%s" % self.money)
def pay(obj): # 归一化设计:不管是哪个类的对象,都调用此函数去实现相似的功能
obj.pay()
a1 = Alipay(100)
pay(a1)
q1 = Qqpay(300)
pay(q1)
w1 = Wechatpay(200)
pay(w1)
使用支付宝支付了100
使用qq支付了300
使用微信支付了200
制定一个类的metaclass是ABCMeta,name这个类就成了一个抽象类(接口类)
抽象类,接口类的主要功能就是建立一个规范
接口继承实质上是要求"作出一个良好的抽象,这个抽象规定了一个兼容借口,是的外部调用者无需关心具体细节,可一视同仁的处理"这在程序设计上叫归一化.
二.多态
1.python处处是多态,不管是什么类型,传入函数,封装到对象中都可以
2.python没有多态,有鸭子类型
1)鸭子类型
class F:
pass
class A(F):
def show(self):
print("A.show")
class B(F):
def show(self):
print("B.show")
def func(obj):
obj.show()
a=A()
func(a)
b=B()
func(b)
A,B类看着就像,都有show方法,互相就称作鸭子
三.封装
1.广义的封装:实例化一个对象,给对像空间封装一些属性
狭义的封装:私有制
2.私有成员:私有静态字段,私有方法,私有属性
1)私有静态字段:
①实例化对象不能访问似有静态字段
②子类名不能访问私有静态字段
③本类的内部可以访问静态字段
④类的外部,派生类均不能访问
class B(A):
__age = 10
def func(self):
print(self.__age)
print(B.__age)
def func1(self):
print(self.__money)
print(B.__money)
b1 = B()
print(b1.name)
print(B.name)
print(b1.__age) # 实例化对象不能访问私有静态字段
print(B.__age) # 类名不能访问私有静态字段
b1.func() # 对于私有静态字段,类的内部可以访问
b1.func1() # 对于私有静态字段,只能在本类内部访问,类的外部,派生类均布不可访问
小明
小明
Traceback (most recent call last):
File "E:/新建文件夹/feiq/Recv Files/day19/day19/05 封装.py", line 59, in
print(b1.__age) # 实例化对象不能访问私有静态字段
AttributeError: 'B' object has no attribute '__age'
10
10
Traceback (most recent call last):
File "E:/新建文件夹/feiq/Recv Files/day19/day19/05 封装.py", line 56, in
B().func1()
File "E:/新建文件夹/feiq/Recv Files/day19/day19/05 封装.py", line 53, in func1
print(self.__money)
AttributeError: 'B' object has no attribute '_B__money'
2)静态私有方法,静态私有属性:与私有静态字段访问情况相同
class A:
name = "小明"
__money = 1000
def __fun(self):
print("in A")
class B(A):
__age = 10
def __func(self):
print("in b")
def func1(self):
# self.__func() # 类的内部可以访问
self.__fun() # 类的外部不能访问父类的私有方法
b1 = B()
b1.__func() # 类外部不能访问私有方法
b1.func1() # 本类的内部可以访问本类的私有方法
b1.func() # 类外部不能访问私有方法
3)访问私有成员的方法:私有成员初始化时候会被处理成 __本类名__成员名,只要访问时以这个名字访问即可
3.面试题
class Parent:
def __func(self):
print("in Parent func")
def __init__(self):
self.__func()
class Son(Parent):
def __func(self):
print("in Son func")
son1 = Son() # 实例化时,Son类中没有__init__,去父类中寻找,执行__init__中的self.__func(),应该先去Son类中寻找__func(),
# 实际上,Parent类中的私有方法已经变成了_Parent__func,Son中并没有此方法,去父类中寻找,找到,执行.
in Parent func