接口类抽象类:
第一版,不好,没有统一化设计,第二版解决.
class QQ: def pay(self,money): print('您用qq支付了%s元' % money) class Ali: def pay(self,money): print('您用支付宝支付了%s元' % money) q1 = QQ() q1.pay(100) a1 = Ali() a1.pay(200)
第二版 ,相安无事,此时来了一个野生程序员.完成了一个微信功能
class QQ: def pay(self,money): print('您用qq支付了%s元' % money) class Ali: def pay(self,money): print('您用支付宝支付了%s元' % money) class Wechat: def wechatpay(self,money): print('您用微信支付了%s元' % money) def pay(obj,money): obj.pay(money) # q1.pay(100) q1 = QQ() a1 = Ali() pay(q1,100) # 统一化设计 pay(a1,200) w1 = Wechat() w1.wechatpay(500)
第三版,重新改版微信支付功能
class QQ: def pay(self,money): print('您用qq支付了%s元' % money) class Ali: def pay(self,money): print('您用支付宝支付了%s元' % money) class Wechat: def pay(self,money): print('您用微信支付了%s元' % money) def pay(obj,money): obj.pay(money) # q1.pay(100) q1 = QQ() a1 = Ali() pay(q1,100) # 统一化设计 pay(a1,200) w1 = Wechat() pay(w1,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(obj,money): obj.pay(money) # a1.pay(200) q1 = QQ() a1 = Ali() pay(q1,100) # 统一化设计 pay(a1,200) w1 = Wechat() pay(w1,500)
第五版 强制制定规范,如果未按照规范执行,就会报错.
from abc import ABCMeta,abstractmethod class Payment(metaclass=ABCMeta): # 抽象类 接口类 规范和约束 metaclass指定的是一个元类 @abstractmethod def pay(self):pass # 抽象方法 class QQ(Payment): def pay(self,money): print('您用qq支付了%s元' % money) def ret(self): print('支付失败....') class Ali(Payment): def pay(self,money): print('您用支付宝支付了%s元' % money) class Wechat(Payment): def pay(self,money): print('您用微信支付了%s元' % money) def pay(obj,money): obj.pay(money) # a1.pay(200) q1 = QQ() a1 = Ali() w1 = Wechat() q1 = QQ() a1 = Ali() pay(q1,100) # 统一化设计 pay(a1,200) w1 = Wechat() pay(w1,500)
用处: 在工作中,如果你要是规定几个类必须有一样的方法, 你要抽象类,制定一个规范,强制其有此方法. python没有多态的概念,但是python崇尚鸭子类型. 定义变量的方法: 1,java c# 需要定义 类型. int i= 3 2,java c# 没有多继承的概念. i = 1 i = 'alex'
鸭子类型: 它看着像鸭子,那么他就是鸭子.
str list tuple str.index() s1 = 'alex' class Str: def index(self): pass class List: def index(self): pass class tuple: def index(self): pass
python中好多不同类但同名的方法不是强制规定,而是约定俗成,像上面这三种类,都同样据有index方法,而且功能相似,
则 他们三个互称为鸭子.
封装: 封装就是将一些属性或者方法(有用的信息)放置在一个空间中. 1,封装 对象的封装.
class Person: def __init__(self,name,age): self.name = name self.age = age p1 = Person('oldboy',1000) p2 = Person('alex',10000) print(p1.name) print(p2.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 def f2(self): pass 静态方法: @staticmethod # 静态方法 def f2():pass 属性: @property # 属性 def hex(self): pass 私有成员: 私有静态字段,私有属性,私有方法 在变量前+ __双下划线.
私有静态字段:
class Animal: __cloth = '皮毛' # _Animal__cloth class Person(Animal): mind = '有思想...' # 第一部分:所有的公有静态变量,公有静态字段 __level = '高等动物' # 第一部分:私有静态变量,私有静态字段 # _Person__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)
在类的外面访问: 私有静态字段是访问不到的.
p1 = Person('alex',1000) print(p1.mind) print(p1.__level) print(Person.__level) print(Person.__dict__) print(Person._Person__level)
可以通过对象._类名__变量名 类名._类名__变量名 可以访问到,但是绝对不要这么访问. 在类的内部: 私有静态字段是可以访问 p1 = Person('alex',1000) p1.func() 父类的私有静态字段,派生类可否访问? 不可访问. p1 = Person('alex',10) print(p1.__cloth) p1.func()
私有方法:
class Animal: def __f1(self):print(1111) # _Animal__f1 class Person(Animal): mind = '有思想...' # 第一部分:所有的公有静态变量,公有静态字段 def __init__(self,name,age): # 构造方法 # 第二部分 动态方法,方法(函数) self.name = name # 公有对象属性 self.age = age self.__sex = sex def __func(self): # _Person__func() print(666) def func1(self): self.__func() # self._Person__func() def func2(self): self.__f1() # self._Person__f1()
类外面访问不到. p1 = Person('OLDBOY',1000) p1.__func() # 类内部可以访问. p1 = Person('OLDBOY',1000) p1.func1() 派生类中也是不能访问的. p1.func2() 私有属性 也是类外部不能访问,派生类不能访问,只能在类内部访问.
class Animal: def __f1(self):print(1111) # _Animal__f1 class Person(Animal): mind = '有思想...' # 第一部分:所有的公有静态变量,公有静态字段 def __init__(self,name,age,sex): # 构造方法 # 第二部分 动态方法,方法(函数) self.name = name # 公有对象属性 self.age = age self.__sex = sex def __func(self): # _Person__func() print(666)
总结: 对于私有成员来说,他加载到内存时,都会加上_类名__变量名,所以你在类的外部,或者派生类中都不可访问.
为什么设置私有成员?
有些变量,方法,属性,只在类内部进行使用即可,不便于(不允许)类外部或者派生类去调用.
class Person: def __init__(self,username,password): # 构造方法 # 第二部分 动态方法,方法(函数) self.usn = username # 公有对象属性 self.__pwd = self.__makepassword() def __makepassword(self): '''复杂的加密过程''' new_pwd = self.__pwd + '666' return new_pwd p1 = Person('alex','123') print(p1.__pwd)
面试题:
class A: def __init__(self): # 2, self = b1对象空间 self.__func() # 默认_A__func() (私有属性必须把前面的类加上) # 3, b1._A__func() def __func(self): # 4 , 默认_A__func() b1._A__func() print('IN A') # print(in A ) class B(A): def __func(self): print('IN B') b1 = B() 1, #B里面没有去A里面找 class A: def __init__(self): # 2,self = b1对象空间 self.func() # 3,b1.func() #b1里面有func函数,所有又去b1里面找 def func(self): print('IN A') class B(A): def func(self): print('IN B') # 4 print(IN B) b1 = B() # 1,B没有去A里面找b1属性 # print(b1.name) # print(b1.func) print(b1.func) print(b1.func())
抽象类接口类: 抽象类和接口类 —— 了解* 在python代码中 抽象类和接口类没有明显的区别 主要就是维持了一种规范 一切皆对象
a = 1 dic = {'k':'v'} lst = [1,2,3] def func(): pass print(type(func)) len(lst) print(dic.__len__(),len(dic)) def len(lst): return lst.__len__() print(len) from abc import ABCMeta,abstractmethod class Pay(metaclass=ABCMeta): @abstractmethod def pay(self,money):pass # 规范
多态:
python天生自带多态
什么是多态
java的多态是通过继承实现的
class Foo:pass class list(Foo):pass class dict(Foo):pass class str(Foo):pass def len(a): print(a) len(1)
Python,动态解释型强类型语言 弱类型 1+'2'参数的数据类型也不需要指定 强类型 同类型之间可以做运算 参数的数据类型也需要指定 抽象类 : 子类必须实现父类中的同名方法——规范代码 在类的位置指定metaclass 是ABCMeta 在指定的方法上面添加@abstractmethod装饰器 目的:规范所有继承这个类的子类 必须实现被@abstractmethod装饰器装饰的这个方法 特点:抽象类和接口类只能被继承不能被实例化
class WechatPay(Pay): def pay(self,money): print('微信支付了%s元'%money) class AliPay(Pay): def pay(self, money): print('支付宝支付了%s元' % money) class ApplePay(Pay): def pay(self,money): print('apple支付了%s元' % money) def payment(obj,money): obj.pay(money) wp = WechatPay() payment(wp,100) # 编程的习惯 —— 归一化设计 wp.pay(100) ap = AliPay() payment(ap,100) ap.pay(100) app = ApplePay() payment(app,100)
规范
接口类
python天生支持多继承,对于python来说抽象类和接口类没有区别
接口类是python特有的,因为python直接用类就可以实现接口的效果
python没有‘接口这种数据类型,java中有
java语言是不支持多继承的
from abc import ABCMeta,abstractmethod class Walk_Animal(metaclass=ABCMeta): @abstractmethod def walk(self):pass class Fly_Animal(metaclass=ABCMeta): @abstractmethod def fly(self):pass class Swim_Animal(metaclass=ABCMeta): @abstractmethod def swim(self):pass class Tiger(Walk_Animal,Swim_Animal): def walk(self): print('walk') def swim(self): print('swim') class Parrot: def walk(self): print('walk') def fly(self): print('fly') class Swan: def walk(self): print('walk') def fly(self): print('fly') def swim(self): print('swim')
封装: 封装 成一个函数 封装 成一个类 封装:面向对象的特性 class A: 私有静态属性: __静态属性 = 'aaa'#私有属性 print(__静态属性)#__静态属性,_类名__名字 在一个变量之前 ,加上两个双下划线是有特殊意义的 加上了这个双下划线,这个变量就变成私有的 print(A.__静态属性) #报错 私有的名字不能在类的外部使用 print(A.__dict__) print(A._A__静态属性)#从语法的角度上不允许你直接调用的 A.__wahaha = 'hahaha'#在一个类的外部是不可能定义一个私有的名字的 print(A.__dict__)
私有的对象属性:
class Room: def __init__(self,owner,id,length,width,height): self.owner = owner self.id = id self.__length= length self.__width = width self.__height = height def area(self): return self.__lenght*self.__width r = Room('文杰',302,2,1.5,0.5) print(r.area())
私有的方法:
不希望从外部去调用这个方法,不独立完成一个功能,而是类整体完成某个功能的一部分。不能被子类继承,在类的内部使用的时候自动变形:类__名字
class Student: 对密码进行加密 def __init__(self,name,pwd): self.name = name self.__pwd = pwd def __getpwd(self): return self.__pwd[::-1] def login(self): self.__getpwd() Student().__getpwd
面试题:
class A: def __init__(self): self.__func() #self._A__func() def __func(self): print('A') class B(A): def __func(self): print('B') B() # _B__func() class A: def __init__(self): self.__func() def __func(self): #_A__func print('A') class B(A): # def __func(self): # print('B') def __init__(self): self.func() # _B__func() B()
名字: 公有的 在类的外部用 内部的 子类用 保护的 子类用 内不用 __私有的 在类的内部用