面向对象>>>抽象类>>>鸭子类型>>>封装

一.抽象类:

  假如老板让你实现一个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)
#这样你就设置成私有成员

  

原文地址:https://www.cnblogs.com/while-number/p/9253101.html