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
    无限的我,现在才开始绽放,从东边的第一缕阳光到西边的尽头
  • 相关阅读:
    linux内核的配置
    数据库常用SQL语句(二):多表连接查询
    数据库常用SQL语句(三):子查询
    数据库常用SQL语句(一):常用的数据库、表操作及单表查询语句
    数据库管理系统软件的软件架构
    Java对象的序列化
    关于重写对象equals方法的问题
    对Spring的理解
    Myeclipse项目工程目录中各种Libraries的含义
    对JDBC的使用理解
  • 原文地址:https://www.cnblogs.com/huangqihui/p/9373062.html
Copyright © 2011-2022 走看看