zoukankan      html  css  js  c++  java
  • python面向对象 : 抽象类(接口类),多态,封装(私有制封装)

    一. 抽象类(接口类)

      与java一样, python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类, 它的特殊之处在于只能被继承, 不能被实例化.

      从设计角度去看, 如果类是从现实对象抽象而来的, 那么抽象类就是基于类抽象而来的。

        从实现角度来看, 抽象类与普通类的不同之处在于: 抽象类中有抽象方法, 该类不能被实例化, 只能被继承, 且子类必须实现抽象方法. 这一点与接口有点类似, 但其实是不同的. 

      实现不同的支付方式:

      

    class Alipay:
        def __init__(self, money):
            self.money = money
    
        def alipay(self):
            print('使用支付宝支付了%s元' % self.money)
    
    
    class Jdpay:
        def __init__(self, money):
            self.money = money
    
        def jdpay(self):
            print('使用京东支付了%s元' % self.money)
    
    
    a = Alipay(500)
    a.alipay()  # 使用支付宝支付了500元
    j = Jdpay(200)
    j.jdpay()  # 使用京东支付了200元

    虽然都实现了支付,但是两个支付都是相同的功能,但调用方却不一样,可以把调用方设置一样.

    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()  
    
    
    a = Alipay(500)
    pay(a)  # 调用函数pay,把对象a穿进去,并执行函数语句
    j = Jdpay(200)
    pay(j)  # 调用函数pay,把对象j穿进去,并执行函数语句
    # 调用方都是函数pay 归一化设计

      虽然设置了一个pay函数,但是有可能后面接手你程序的人并不会发现,含是按照第一种的方法实现新的支付方式,所以我们要确保在之后添加的类中要有pay函数.

    from abc import ABCMeta, abstractmethod  # 从abc模块引进ABCMeta,abstractmethod
    
    
    class Allpay:
        @abstractmethod  # 在需要制定模板的函数上写一句
        def pay(self):   # 制定规范,子类中必须有pay方法,否则报错
            pass
    
    
    class Alipay(Allpay):
        def __init__(self, money):
            self.money = money
    
        def pay(self):
            print('使用支付宝支付了%s元' % self.money)
    
    
    class Jdpay(Allpay):
        def __init__(self, money):
            self.money = money
    
        def pay(self):
            print('使用京东支付了%s元' % self.money)
    
    
    class Wechatpay(Allpay):
        def __init__(self, money):
            self.money = money
    
        # def wechatpay(self):  #函数名不是pay会报错
        #     pass
        def pay(self):
            print('使用微信支付了%s元' % self.money)
    
    
    def pay(obj):
        obj.pay()
    
    
    a = Alipay(500)
    pay(a)  # 使用支付宝支付了500元
    j = Jdpay(200)
    pay(j)  # 使用京东支付了200元
    w = Wechatpay(700)
    pay(w)  # 使用微信支付了700元

    二. 多态

      python不支持多态, 也不用支持多态,因为python处处是多态, python是一种多态语言, 参数在传入之前是无法确定参数类型的. 崇尚鸭子类型

       鸭子类型 : 看着像鸭子,他就是鸭子, 下面的类有相同功能的方法, 都互称为鸭子.

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

    三. 封装

      封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容。所以,在使用面向对象的封装特性时,需要:将内容封装到某处, 然后从某处调用被封装的内容.

      封装分为广义的封装和狭义的封装

      广义的封装: 实例化一个对象,给对象空间封装一些属性.   

    class Animal:
        def __init__(self,name,sex,age):
            self.name = name  #广义的封装
            self.age = age
            self.sex = sex

      狭义的封装: 私有制.

      私有成员 : 私有静态字段, 私有方法, 私有对象属性

      私有静态字段:

      在类外部引用私有静态字段

    class Pay:
        __money = 1000  # 定义私有静态变量__money
    
        def pay(self):
            pass
    
    
    p = Pay()
    p.__money  # 报错,在类外部对象无法引用私有静态字段__money
    Pay.__money  # # 报错,在类外部类名无法引用私有静态字段__money

      在类内部引用私有静态字段

    class Pay:
        __money = 1000  # 定义私有静态变量__money
    
        def pay(self):
            print(p.__money)  # 在类内部对象可以引用私有静态字段__money
            print(Pay.__money)  # 在类内部类名可以引用私有静态字段__money
    
    p = Pay()
    p.pay()
    # 1000
    # 1000

      在子类引用私有静态字段

    class Money:
        __money = 1000  # 定义私有静态变量__money
    
    
    class Pay(Money):
    
        def pay(self):
            pass
            print(p.__money)  # 在子类内部对象不能引用父类的私有静态字段__money
            print(Pay.__money)  # 在子类内部类名不能引用父类的私有静态字段__money
    
    
    p = Pay()
    # p.__money  # 子类的对象无法引用父类的私有静态字段__money
    # Pay.__money  # 子类名无法引用父类的私有静态字段__money
    p.pay()

      总结:对于私有静态字段来说,只能在本类中内部访问,类的外部,派生类(子类)均不可访问.

    # 可以访问,但是工作中千万不要用 : '__类名私有静态字段'
    # print(Pay._Pay__money)
    # print(Pay.__dict__)

      私有方法:对于私方法来说,只能在本类中内部访问,类的外部,派生类(子类)均不可访问.

    class B:
        def __f1(self):
            print('777')
    
    class A(B):
        def __func(self):
            print('666')
    
        def func1(self):
            self.__func()  # 类内部可以访问
            self.f1()  # 子类无法访问父类的私有方法
    
    a = A()
    # a.__func()  # 类外部对象不能访问
    # A.__func()  # 类外部类名不能访问
    a.func1()
    # 666
    # 666

      私有属性

    class A:
    
        def __init__(self,name,age,weight):
    
            self.name = name
            self.__age = age
            self.__weight = weight
        def func(self):
            print(self.__age)  #类内可以引用私有属性
    a1 = A('jsck',18,45)
    print(a1.name)
    print(a1.__dict__)  # {'name': 'jsck', '_A__age': 18, '_A__weight': 45}
    # print(a1.__age)  # 类外无法引用私有属性
    a1.func()

      面试题

    class Parent:
        def __func(self):
            print('in Parent func')
    
        def __init__(self):  # 自动执行__init__方法
            self.__func()  # self.__func() =>> self.__Parent__func
    
    
    class Son(Parent):
        def __func(self):
            print('in Son func')
    
    
    son1 = Son()  # in Parent func
    无限的我,现在才开始绽放,从东边的第一缕阳光到西边的尽头
  • 相关阅读:
    Windows 8实例教程系列 开篇
    qt 开发发布于 windeploy.exe
    qt qoci 测试验证
    vmware vmx 版本不兼容
    qt oracle
    vc qt dll
    QOCIDriver unable to create environment
    qoci 编译完 放置位置 具体根据情况
    calling 'lastError' with incomplete return type 'QSqlError' qsqlquer
    Hbase 操作工具类
  • 原文地址:https://www.cnblogs.com/huangqihui/p/9373062.html
Copyright © 2011-2022 走看看