面向对象之:封装,多态,以及类的约束

1.封装

把很多数据封装到⼀个对象中. 把固定功能的代码封装到⼀个代码块, 函数, 对象, 打包成模块. 这都属于封装的思想. 具体的情况具体分析. 比如. 你写了⼀个很⽜B的函数. 那这个也可以被称为封装. 在⾯向对象思想中. 是把⼀些看似⽆关紧要的内容组合到⼀起统⼀进⾏存储和使⽤. 这就是封装.

顾名思义就是将内容封装到某个地方,以后再去调用被封装的内容

封装的步骤

  • 将内容封装到某处

    class A:
        def __init__(self,name):
            self.name=name
            self.age=age
    obj1=A('张三',18)
    #将张三和18封装到name和age属性中
  • 从某处调用封装的内容

    直接调用

    class A:
        def __init__(self,name):
            self.name=name
            self.age=age
    obj1=A('张三',18)
    print(obj1.name)

    间接调用

    class A:
        def __init__(self,name):
            self.name=name
            self.age=age
        def get(self):
            print(self.name)
    obj1=A('张三',18)
    obj1.get()

    总结,对于面向对象的封装来说,其实就是使用构造方法将内容封装到 对象 中,然后通过对象直接或者self间接获取被封装的内容。

2.多态

多态,同一个对象,多种形态。python默认支持多态。

3.鸭子类型

python中有一句谚语说的好,你看起来像鸭子,那么你就是鸭子。
对于代码上的解释其实很简答:
class A:
    def f1(self):
        print('in A f1')
    
    def f2(self):
        print('in A f2')
​
​
class B:
    def f1(self):
        print('in A f1')
    
    def f2(self):
        print('in A f2')
        
obj = A()
obj.f1()
obj.f2()
​
obj2 = B()
obj2.f1()
obj2.f2()

A 和 B两个类完全没有耦合性,但是在某种意义上他们却统一了一个标准。
对相同的功能设定了相同的名字,这样方便开发,这两个方法就可以互成为鸭子类型。
这样的例子比比皆是:str tuple list 都有 index方法,这就是统一了规范。
str bytes 等等 这就是互称为鸭子类型。

4.类的约束

版本一:
# class Wechat_Pay:
#
#     def pay(self,money):
#         print(f'微信支付了{money}元')
#
#
# class Ali_Pay:
#
#     def pay(self, money):
#         print(f'阿里支付了{money}元')
#
# wp = Wechat_Pay()
# ap = Ali_Pay()
#
# wp.pay(100)
# ap.pay(200)

版本二 统一化接口

# class Wechat_Pay:
#
#     def pay(self,money):
#         print(f'微信支付了{money}元')
#
#
# class Ali_Pay:
#
#     def pay(self, money):
#         print(f'阿里支付了{money}元')
#
#
# def pay(obj, money):  # 归一化设计,统一接口
#     # wp.pay(100)
#     obj.pay(money)
#
# wp = Wechat_Pay()
# ap = Ali_Pay()
#
# pay(wp,100)
# pay(ap,200)
版本三: 来了一个野生程序员,增加qq支付功能。
# class Wechat_Pay:
#
#     def pay(self,money):
#         print(f'微信支付了{money}元')
#
#
# class Ali_Pay:
#
#     def pay(self, money):
#         print(f'阿里支付了{money}元')
#
#
# class QQ_Pay:
#
#     def zhifu(self,money):
#         print(f'qq支付了{money}元')
#
#
# def pay(obj, money):  # 归一化设计,统一接口
#     # wp.pay(100)
#     obj.pay(money)
# wp = Wechat_Pay()
# ap = Ali_Pay()
#
# pay(wp,100)
# pay(ap,200)
# qp = QQ_Pay()
# qp.zhifu(300)

对某些类里面的重要的方法强行加一些约束,规范化。
最简单的约束:
# class Payment:
#
#     def pay(self,money):
#         pass
#
#
# class Wechat_Pay(Payment):
#
#     def pay(self,money):
#         print(f'微信支付了{money}元')
#
#
# class Ali_Pay(Payment):
#
#     def pay(self, money):
#         print(f'阿里支付了{money}元')
#
#
# class QQ_Pay(Payment):
#
#     def zhifu(self,money):
#         print(f'qq支付了{money}元')
#
#
# def pay(obj, money):  # 归一化设计,统一接口
#     # wp.pay(100)
#     obj.pay(money)

制定约束的方式一:
在父类定义必须要创建的方法,然后让此方法主动抛出异常。

# class Payment:
#
#     def pay(self, money):
#         raise Exception('子类必须定义此方法')
#
# class Wechat_Pay(Payment):
#
#     def pay(self, money):
#         print(f'微信支付了{money}元')
#
#
# class Ali_Pay(Payment):
#
#     def pay(self, money):
#         print(f'阿里支付了{money}元')
#
#
# class QQ_Pay(Payment):
#
#     def zhifu(self, money):
#         print(f'qq支付了{money}元')
#
#
# def pay(obj, money):  # 归一化设计,统一接口
#     # wp.pay(100)
#     obj.pay(money)
#
# qp = QQ_Pay()
# pay(qp,400)

方式二:借助于抽象(接口)类,利用元类metclass去实现完全约束。
from abc import ABCMeta, abstractmethod
​
class Payment(metaclass=ABCMeta):  # 抽象类,接口类 制定一个强硬的规范约束。
    @abstractmethod
    def pay(self, money):
        passclass Wechat_Pay(Payment):
​
    def pay(self, money):
        print(f'微信支付了{money}元')
​
class Ali_Pay(Payment):
​
    def pay(self, money):
        print(f'阿里支付了{money}元')
​
​
class QQ_Pay(Payment):
​
    def zhifu(self, money):
        print(f'qq支付了{money}元')
​
​
def pay(obj, money):  # 归一化设计,统一接口
    # wp.pay(100)
    obj.pay(money)
​
qp = QQ_Pay()

规范化约束方式一

在父类定义必须要创建的方法,然后让此方法主动抛出异常。

制定约束的方式一:

# class Payment:
#
#     def pay(self, money):
#         raise Exception('子类必须定义此方法')
#
# class Wechat_Pay(Payment):
#
#     def pay(self, money):
#         print(f'微信支付了{money}元')
#
#
# class Ali_Pay(Payment):
#
#     def pay(self, money):
#         print(f'阿里支付了{money}元')
#
#
# class QQ_Pay(Payment):
#
#     def zhifu(self, money):
#         print(f'qq支付了{money}元')
#
#
# def pay(obj, money):  # 归一化设计,统一接口
#     # wp.pay(100)
#     obj.pay(money)
#
# qp = QQ_Pay()
# pay(qp,400)

方式二

借助于抽象(接口)类,利用元类metclass去实现完全约束。

from abc import ABCMeta, abstractmethod
​
class Payment(metaclass=ABCMeta):  # 抽象类,接口类 制定一个强硬的规范约束。
    @abstractmethod
    def pay(self, money):
        passclass Wechat_Pay(Payment):
​
    def pay(self, money):
        print(f'微信支付了{money}元')
​
class Ali_Pay(Payment):
​
    def pay(self, money):
        print(f'阿里支付了{money}元')
​
class QQ_Pay(Payment):
​
    def zhifu(self, money):
        print(f'qq支付了{money}元')
​
def pay(obj, money):  # 归一化设计,统一接口
    # wp.pay(100)
    obj.pay(money)
​
qp = QQ_Pay()

总结,约束. 其实就是⽗类对⼦类进⾏约束. ⼦类必须要写xxx⽅法. 在python中约束的⽅式和⽅法有两种:

  • 使⽤抽象类和抽象⽅法, 由于该⽅案来源是java和c#. 所以使⽤频率还是很少的

  • 使⽤⼈为抛出异常的⽅案. 并且尽量抛出的是NotImplementError. 这样比较专业, ⽽且错误比较明确.(推荐)

 

posted @ 2019-12-23 21:19  小辉的  阅读(45)  评论(0)    收藏  举报
/*小图标*/