归一化
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(200)
j1 = Jdpay(100)
pay(a1) # 归一化设计
pay(j1)
抽象类
from abc import ABCMeta, abstractmethod
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self): pass
@abstractmethod # 定义抽象方法
def func(self): pass
class Alipay(Payment):
def __init__(self, money):
self.money = money
def pay(self):
print("使用阿里支付了%d" % self.money)
def func(self):
print("func")
self.pay()
a1 = Alipay(100)
a1.func()
3.多态
python 不管什么类型,传入函数,封装到对象中都可以
鸭子类型 : 看着像鸭子,他就是鸭子
1 class Duck():
2 def walk(self):
3 print('I walk like a duck')
4 def swim(self):
5 print('i swim like a duck')
6
7 class Person():
8 def walk(self):
9 print('this one walk like a duck')
10 def swim(self):
11 print('this man swim like a duck')
可以很明显的看出,Person类拥有跟Duck类一样的方法,当有一个函数调用Duck类,并利用到了两个方法walk()和swim()。我们传入Person类也一样可以运行,函数并不会检查对象的类型是不是Duck,只要他拥有walk()和swim()方法,就可以正确的被调用。
再举例,如果一个对象实现了__getitem__方法,那python的解释器就会把它当做一个collection,就可以在这个对象上使用切片,获取子项等方法;如果一个对象实现了__iter__和next方法,python就会认为它是一个iterator,就可以在这个对象上通过循环来获取各个子项。
4.封装
- 广义的封装: 实例化一个对象,给对象空间封装一些属性.
- 狭义的封装: 私有制.
**凡是私有的在加载的时候都会自动在名前面加上_类名(访问私有时加_类名就可以访问)**
私有成员:私有静态字段(在类外面,实例化对象不能访问,类名也不能访问,对于私有静态变量,类的外面不能访问,类的内部无论是self.还是类.都可以访问,父类的私有静态变量,子类也访问不了)
私有方法(实例化对象的类名调用不能访问,即类外不能访问,类内部可以访问,只能用self.调用,父类的私有方法子类也不能调用)
私有对象属性
5.面试题
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()//in Parent func
先从对象本身中去找,在到子类再到,父类(注意加载过程中的更改)
6.可变变量
p1和p2在实例化后,对象空间中没有name这个属性,所以访问的类中的name(故所有的值相同)