1.接口类,抽象类.
2.鸭子类型(Python多态)(Python三大特性之一)Python封装
1.接口类和抽象类只是在工作中书写的一种规范.
class QQ:
def pay(self,money):
print("使用QQ支付%s"%money)
class Ali:
def pay(self,money):
print("使用支付宝支付%s"%money)
q = QQ()
q.pay(100)
a = Ali()
a.pay(200)
上面的例子,没有统一化.不方便之后的开发
class QQ:
def pay(self,money):
print("使用QQ支付%s"%money)
class Ali:
def pay(self,money):
print("使用支付宝支付%s"%money)
def pay(self,money):
self.pay(money)
q = QQ()
a = Ali() #这样就实现了统一化
pay(q,100)
pay(a,200)
以上这版实现了统一化,但是交接的时候,新来的看不懂就会按照自己的方法写.看下面
class QQ:
def pay(self,money):
print("使用QQ支付%s"%money)
class Ali:
def pay(self,money):
print("使用支付宝支付%s"%money)
class Wechat:
def wepay(self,money):
print("使用微信支付%s"%money)
def pay(self,money):
self.pay(money)
q = QQ()
a = Ali()
pay(q,100)
pay(a,200)
w = Wechat() #新来的员工按照自己方法添加了一种,但是不规范.
w.wepay(500)
我们看一下下面的方法.
class Payment:
def pay(self):pass
class QQ(Payment):
def pay(self,money):
print("使用QQ支付%s"%money)
class Ali(Payment):
def pay(self,money):
print("使用支付宝支付%s"%money)
class Wechat(Payment):
def pay(self,money):
print("使用微信支付%s"%money)
def pay(self,money):
self.pay(money)
q = QQ()
a = Ali()
w = Wechat()
pay(q,100)
pay(a,200)
pay(w,500)
以上便是为了规避方法不统一的方法.下面的例子便是强制统一,不同一便报错.
from abc import ABCMeta , abstractmethod
class Payment(metaclass = ABCMeta):
@abstractmethod
def pay(self):pass
class QQ(Payment):
def pay(self,money):
print("使用QQ支付%s"%money)
class Ali(Payment):
def pay(self,money):
print("使用支付宝支付%s"%money)
class Wechat(Payment):
def pay(self,money):
print("使用微信支付%s"%money)
def pay(self,money):
self.pay(money)
q = QQ()
a = Ali()
w = Wechat()
pay(q,100)
pay(a,200) #强制统一化.没有统一便会报错
pay(w,500)
抽象类(接口类)用处:在工作中,如果要是规定几个类必须有一样的方法,要抽象类.制定一个规范,强制其有此方法.
Python没有多态的概念,但是Python崇尚鸭子类型.
Python中好多不同类但同名的方法不是强制规定,而是约定俗成的,像str,list,tuple这三种类,都同样具有index方法,而且功能相似,则他们三个互称为鸭子.
封装就是将一些属性或者方法(有用的信息)放置在一个空间中.
1.封装 对象的封装
class A:
def __init__(self,name,age):
self.name = name
self.age = age
p = A("alex",23)
print(p.name)
2.封装(私有成员)
类的结构分析:
class Person:
mind = "有思想" #第一部分:所有的公有静态变量,公有静态字段
__level = "高等动物" #第一步分:私有静态变量,私有静态字段
def __init__(self,name,age,sex): #构造方法,第二部分:动态方法,方法(函数)
self.name = name
self.age = age #公有对象属性
self.__sex = sex #私有对象属性
def func(self): #第二部分:普通方法
print(666)
def __func1(self): #第二部分:私有方法
print(777)
@staticmethod #静态方法
def f2():pass
@classmethod #类方法
def f2(self):pass
@property #属性
def hex(self):pass
类的整体分类:
第一部分:公有静态字段: mind = "有思想"
私有静态字段: __level = "高等动物"
第二部分:特殊方法(__init__,__str__ ....)
普通方法:def func(self)
私有方法:def __func1(self)
类方法:@classmethod
静态方法:@staticmethod
属性:@property
私有成员:私有静态字段,私有属性,私有方法.在变量前加__双下划线.
class Animal:
__cloth = "有皮毛"
class Person(Animal):
mind = "有思想"
__level = "高等动物"
def __init__(self,name,age):
self.name = name
self.age = age
def func(self):
print(self.__level) #类自己在内部访问自己的私有属性
print(self._Animal__cloth) #知道这种方法可以,但是禁止使用.
print(self.__cloth) #派生类不可访问父类的私有属性
在类的外面访问:私有静态字段是访问不到的.
p = Person("alex",100)
print(p.mind)
print(p.__level) #这样访问会报错.
print(Person.__level) #这样访问也是会报错的.
print(Person.__dict__)
print(Person._Person__level) #这个方法知道就可以了,但是禁止使用.
#可以通过 对象._类名__变量名 类名._类名__变量名 可以访问到,但是绝对不要这样做
在类的内部: 私有静态字段是可以访问的.
p.func()
父类的私有字段,派生类是否可以访问? 答案是:不可以
print(p.__cloth)
p.func() #这两种都会报错.因为在外部是不可访问父类的私有字段.
私有方法:
class Animal:
def f1(self):
print(111)
class Person(Animal):
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.__sex = sex
def __func(self):
print(6666)
def func1(self):
self.__func()
def func2(self):
self.__f1()
类外面访问不到:
p = Person("oldboy",200)
p.__func()
类的内部可以访问:
p.func1()
派生类也是访问不到的
p.func2()
私有属性也是类外部不能访问,派生类不能访问,只能类内部访问.
总结:对于私有成员来说,加载到内存时,都会加上_类名__变量名,所以在类的外部或者派生类中都不可访问.
为什么设置私有成员?
有些变量,方法,属性只在类内部进行使用即可不便于(不允许)类外部或者派生类去调用.
class A:
def __init__(self):
self.__func()
def __func(self):
print("in A")
class B(A):
def __func(self):
print("in B")
b = B()
这是一道面试题, 打印的结果是什么,为什么结果是这样的.