zoukankan      html  css  js  c++  java
  • python学习第17天----接口类/抽象类、多态、封装

    1.接口类

    python是没有接口这个概念的

    1)引:归一化设计

    #第一版:写一个两种支付功能的程序

    class Alipay:
        def __init__(self,money):
            self.money = money
        def pay(self):
            print("用支付宝支付了%s钱"% self.money)
    class JDpay:
        def __init__(self,money):
            self.money = money
        def pay(self):
            print("用京东支付了%s钱" % self.money)
    a1 = Alipay(100)
    a1.pay()
    j1 = JDpay(200)
    j1.pay()          #同样是支付的功能,但是支付的指令不一样,未统一化设计
    输出:
    用支付宝支付了100钱
    用京东支付了200钱
    View Code

    问题:同样是支付的功能,但是支付的指令不一样,未统一化设计

    #第二版:不同的支付方式,调用同样的支付指令,统一化设计

    class Alipay:
        def __init__(self,money):
            self.money = money
        def pay(self):
            print("用支付宝支付了%s钱"% self.money)
    class JDpay:
        def __init__(self,money):
            self.money = money
        def pay(self):
            print("用京东支付了%s钱" % self.money)
    def pay(obj):
        obj.pay()
    a1 = Alipay(100)
    j1 = JDpay(200)
    pay(a1)
    pay(j1)       #归一化设计
    输出:
    用支付宝支付了100钱
    用京东支付了200钱
    View Code

    2)接口类/抽象类:

    1)定义:制定一个规范,所有继承基类的子类,必须要有基类的抽象方法 ,如果没有基类的抽象方法,子类在实例化对象的时候就会报错

    #如果子类继承父类,为重写父类的抽象方法,可强制程序报错

    from abc import ABCMeta,abstractmethod
    class Payment(metaclass=ABCMeta):
        @abstractmethod
        def pay(self):
            pass
    class Alipay(Payment):
        def __init__(self,money):
            self.money = money
        def pay(self):
            print("用支付宝支付了%s钱"% self.money)
    class JDpay(Payment):
        def __init__(self,money):
            self.money = money
        def pay(self):
            print("用京东支付了%s钱" % self.money)
    class Wechat(Payment):
        def __init__(self,money):
            self.money = money
        def wechat_pay(self):          #未在子类重写父类抽象方法
            print("用微信支付了%s块" % self.money)
    def pay(obj):
        obj.pay()
    a1 = Alipay(100)
    pay(a1)
    j1 = JDpay(200)
    pay(j1)
    w1 = Wechat(300)
    w1.wechat_pay()
    报错如下:
    TypeError: Can't instantiate abstract class Wechat with abstract methods pay
    View Code

    #子类重写父类抽象方法

    from abc import ABCMeta,abstractmethod
    class Payment(metaclass=ABCMeta):
        @abstractmethod
        def pay(self):
            pass
    class Alipay(Payment):
        def __init__(self,money):
            self.money = money
        def pay(self):
            print("用支付宝支付了%s钱"% self.money)
    class JDpay(Payment):
        def __init__(self,money):
            self.money = money
        def pay(self):
            print("用京东支付了%s钱" % self.money)
    class Wechat(Payment):
        def __init__(self,money):
            self.money = money
        def pay(self):
            print("用微信支付了%s块" % self.money)
    def pay(obj):
        obj.pay()
    a1 = Alipay(100)
    pay(a1)
    j1 = JDpay(200)
    pay(j1)
    w1 = Wechat(300)
    w1.pay()
    输出:
    用支付宝支付了100钱
    用京东支付了200钱
    用微信支付了300块
    View Code

    注:必须要在抽象方法前加上@abstractmethod装饰器,否则子类有无重写父类抽象方法都不影响程序,即程序不会报错

    2.多态、封装

    1)python多态:python是没有多态这个感念的(没有多态的示例),因为python中处处是多态;因为不管是什么数据类型,传入函数,封装到对象中都可以,python是可以多继承的,其他语言不可以

    2)python没有多态,但是它又有鸭子类型

    #多个类,每一个类中都有同名的方法,且这些方法功能类似;这些类,都互称为鸭子

    class Str:
        def index(self):
            pass
    class List:
        def index(self):
            pass
    class Tuple:
        def index(self):
            pass
    View Code

    3.封装

    1)广义封装:实例化一个对象,给对象空间封装一些属性、给类中封装静态字段

    2)狭义的封装:私有制,只有某些对象可以调用

    3)私有成员:分为私有静态字段、私有方法、私有对象属性

    #python中各变量和方法

    class A:
    
        company_name = '百度'  # 静态变量(静态字段)
        __iphone = '1353333xxxx'  # 私有静态变量(私有静态字段)
    
    
        def __init__(self,name,age): #特殊方法
    
            self.name = name  #对象属性(普通字段)
            self.__age = age  # 私有对象属性(私有普通字段)
    
        def func1(self):  # 普通方法
            pass
    
        def __func(self): #私有方法
            print(666)
    
    
        @classmethod  # 类方法
        def class_func(cls):
            """ 定义类方法,至少有一个cls参数 """
            print('类方法')
    
        @staticmethod  #静态方法
        def static_func():
            """ 定义静态方法 ,无默认参数"""
            print('静态方法')
    
        @property  # 属性
        def prop(self):
            pass
    转自:https://www.cnblogs.com/jin-xin/articles/9214247.html
    View Code

    ①私有静态字段:在变量名前加两下划线如【__name】

    #实例化对象不能直接访问私有静态字段

    class A:
        name = "阿狸"
        __age = 18
        def func(self):
            print("In func...")
    a1 = A()
    print(a1.name)
    print(a1.__age)       #实例化对象不能直接访问私有静态字段
    报错:
    AttributeError: 'A' object has no attribute '__age'
    阿狸
    View Code

    #类名不能直接访问私有静态变量

    class A:
        name = "阿狸"
        __age = 18
        def func(self):
            print("In func...")
    a1 = A()
    print(A.__age)
    输出:
    AttributeError: 'A' object has no attribute '__age'
    View Code

    总结:对于私有静态变量,类的外部不能访问

    #对于私有静态字段,类的内部可以访问

    class A:
        name = "阿狸"
        __age = 18
        def func(self):
            print("In func...")
            print(A.__age)
    a1 = A()
    输出:
    In func...
    18
    View Code

    #对于私有静态字段,子类不可以访问

    总结:对于私有静态字段来说,只能在本类的内部访问,类的外部、派生类都不能访问

    备注:实际是可以在类的外部对私有静态字段进行修改的,因为从本质上来说,定义一个类就相当于开辟了一块内存空间,对于私有静态字段如【__name】,实际在内存空间中存的是【_A_name】,所以可在类外直接通过_A__name改变私有静态字段,但是非常不建议这么做

    class A:
        name = "阿狸"
        __age = 18
        def func(self):
            print("In func...")
    print(A._A__age)
    print(A.__dict__)
    输出:
    18
    {'_A__age': 18, 'name': '阿狸', 'func': <function A.func at 0x000001504A05A048>, '__module__': '__main__', '__doc__': None, '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>}
    View Code

    ②私有方法:在方法名前加两个下划线【__方法名】

    #对于私有方法,在类外不能访问,类的派生类也不能访问,只能在类的内部访问

    class A:
        def __func(self):
            print("In func...")
        def func_2(self):
            self.__func()
    a1 = A()
    a1.func_2()
    输出:
    In func...
    View Code

    本质:在开辟内存空间时,把私有方法名改为了【_类名__方法名】

    例:写入如下程序的输出

    class Parent:
        def __func(self):
            print('in Parent func')
    
        def __init__(self):
            self.__func()
    
    class Son(Parent):
        def __func(self):
            print('in Son func')
    
    son1 = Son()
    输出:
    in Parent func
    View Code
  • 相关阅读:
    地震逃生【网络流】
    地震逃生【网络流】
    【杭电】[2002]计算球体积
    【杭电】[2002]计算球体积
    【杭电】[2003]求绝对值
    【杭电】[2003]求绝对值
    写在正式写博客之前——博客的意义
    写在正式写博客之前——博客的意义
    初识ACM——活泼的精灵
    初识ACM——活泼的精灵
  • 原文地址:https://www.cnblogs.com/piaolaipiaoqu/p/13883592.html
Copyright © 2011-2022 走看看