一.抽象类:
假如老板让你实现一个QQ,支付宝,支付功能
你是这样做的:
class QQ: def pay(self,money): print("您用QQ支付了%s" % money) class Ali: def pay(self,money): print("您用QQ支付宝了%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("您用QQ支付宝了%s" % money) def pay(obj,money): obj.pay(money) # q1 = QQ() # a1 = Ali() # pay(q1,100) # 统一化设计 # pay(a1,200)
老板一看;不错
可是公司来了一个野生程序员 这个项目给他了
要求添加一个微信支付,
他是这样写的:
class QQ: def pay(self, money): print("您用QQ支付了%s" % money) class Ali: def pay(self, money): print("您用QQ支付宝了%s" % money) class Wechat: def wechat_pay(self,money): print("您用微信支付宝了%s" % money) def pay(obj,money): obj.pay(money) # q1 = QQ() # a1 = Ali() # w1 = Wechat() # pay(q1,100) # 统一化设计 # pay(a1,200) w1.wechat_pay(500)
老板一看不行啊:拿回去重写
拿回来一看明白了:
改良过的:
class QQ: def pay(self, money): print("您用QQ支付了%s" % money) class Ali: def pay(self, money): print("您用QQ支付宝了%s" % money) class Wechat: def pay(self,money): print("您用微信支付宝了%s" % money) def pay(obj,money): obj.pay(money) # q1 = QQ() # a1 = Ali() # w1 = Wechat() # pay(q1,100) # 统一化设计 # pay(a1,200) # pay(w1,300)
工作时候为了避免这种规范,我要制定一个规范
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("您用QQ支付宝了%s" % money) class Wechat(Payment): def pay(self,money): print("您用微信支付宝了%s" % money) def pay(obj,money): obj.pay(money) q1 = QQ() a1 = Ali() w1 = Wechat() pay(q1,100) # 统一化设计 pay(a1,200) pay(w1,300)
如果你碰到那种纯纯的他是真不会的你也可以这样做:
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("您用QQ支付宝了%s" % money) class Wechat: def apay(self,money): #未按照规范方法 print("您用微信支付宝了%s" % money) def pay(obj,money): obj.pay(money) q1 = QQ() a1 = Ali() w1 = Wechat() pay(q1,100) # 统一化设计 pay(a1,200) pay(w1,300) # 未按照规范的方法 报错 #用处:在工作中,如果你要是规定及各类必须有一样的方法, # 你要抽象类,指定一个规范,强制其有此方法
#python没有多态的概念,但是python崇尚鸭子类型
定义变量的方法:
1.java C#: 需要定义类型 int i = 3 str i = alex
2.java C#:没有多继承的概念
python:
i = 1
i = "alex"
二.鸭子类型: 它看着像鸭子,那么它就是鸭子
比如说:
# str list tuple
s1 = "alex" s2 = str('123') 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',6) print(p1.name) print(p2.name)
2.封装(私有成员.)
类的结构分析:
类整体分类:
class Person: mind = "有思想" # 第一部分:所有的公有静态变量,公有静态字段 __level = "高等动物" # 第一部分:私有静态变量,私有静态字段 def __init__(self,name,age,sex): #构造方法#第二部分,动态方法,(函数) # 特殊方法__XXXX__(self): self.name=name #公有对象属性 self.age=age self.__sex =sex #私有对象属性 def func(self): # 第二部分: 普通方法 print(666) def __func1(self): #第二部分:私有方法,(私有函数) print(777) @staticmethod # 静态方法 def f2():pass @staticmethod def f3(self):pass #类方法 @staticmethod # 属性 def hex(self):pass
第一部分:公有静态字段 mind = '有思想',私有静态字段 __midn = 'alex"
第二部分:
特殊方法:(__init__(公有属性,私有属性),__str__):
普通方法: def func(self):
私有方法: def __func1(self):
类方法: @staticmethod
def f3(self):
属性
私有成员:私有静态字段,私有属性,私有动态方法 在变量前加__双下划綫
私有静态字段:
class Animal: __cloth = '皮毛' #只要类一执行看到双下划綫__他就会变成_Anmal__cloth class Person(Animal): mind = "有思想" # 第一部分:所有的公有静态变量,公有静态字段 __level = "高等动物" # 第一部分:私有静态变量,私有静态字段 def __init__(self,name,age): #构造方法#第二部分,动态方法,(函数) # 特殊方法__XXXX__(self): self.name=name #公有对象属性 self.age=age def func(self): print(self.__level) print(self.__cloth__) #在类外面访问:私有静态字段是访问不到的 p1 =Person('alex',1000) print(p1.mind) print(p1.__level) #不能访问私有变量(字段) print(Person._Person.P__level) #可以访问到 但不建议这么做 #在类的内部:可以访问到 p1.func() # 父类的私有讲台字段,派生类可否访问? 不可访问. print(p1.__cloth) #找不到 p1.func() # 也找不到 #对于私有字段来说 .只有本类可以访问.
私有方法:
class Animal: def __f1(self):print(111) #_Animal__f1 class Person(Animal): mind = "有思想" # 第一部分:所有的公有静态变量,公有静态字段 def __init__(self,name,age,sex): #构造方法#第二部分,动态方法,(函数) # 特殊方法__XXXX__(self): 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('alex',200) p1.__func() #再类内部可以访问 p1.func1() # 派生类中也是不能访问,究其根本. p1.func2() #私有属性 也是类外部,派生类不能访问 #只能在内部访问 # @staticmethod # 静态方法 # def f2():pass # # @staticmethod # def f3(self):pass #类方法 # # @staticmethod # 属性 # def hex(self):pass #总结: ''' 对于私有成员来说,他加载到内存时,都会加上_类名__变量名,所以你在类的外部,或者派生类中都不可访问 为什么设置私有成员? 因为有些变量,方法,属性,只在类的内部进行使用即可,不便于类外部,不便于(不允许)类外部或者派生类使用 ''' class Person(): def __init__(self,usename,password): self.usename=usename self.pwd=password p1 = Person('alex',124) print(p1.pwd) #只要输入password就能找到 class Person(): def __init__(self,usename,password): self.usename=usename self.__password=password p1 = Person('alex',124) print(p1.__pwd) #这样就找不到了 class Person(): def __init__(self,usename,password): self.usename=usename self.__pwd=self.__makepassword() def __makepassword(self): '''复杂的加密过程''' new_pwd = self.__pwd+'666' return new_pwd p1 = Person('alex',124) print(p1.__pwd) #这样你就设置成私有成员