• python面向对象的三个特性


    主要内容:

      1. 抽像类或者接口类

      2. 多态(鸭子模型)

      3.封装

    1. 抽像类或者接口类

    接口类,python是没有接口类的,只是一种规范,强制用户按照这个规范来,如果未按照规范执行,就会报错.

    如下示例:

    from abc import ABCMeta,abstractmethod
    
    class Payment(metaclass=ABCMeta):
        @abstractmethod   ### # 抽象类 接口类  规范和约束  metaclass指定的是一个元类
        def pay(self):   # 抽象方法
            pass
    
    
    class  Alipay(Payment):
        def pay(self,money):
            print("您使用支付宝支付了%s钱" % money)
    class  QQpay(Payment):
        def pay(self,money):
            print("您使用QQ钱包支付了%s钱" % money)
    class  Wechat(Payment):
        def we_pay(self,money):
            print("您使用微信支付支付了%s钱" % money)
    
    def pay(obj,money):
        obj.pay(money)
    
    a1 = Alipay()
    q1 = QQpay()
    w1 = Wechat()
    
    pay(a1,100)
    pay(q1,200)
    pay(w1,300)

    2 多态,或者鸭子模型

    用处: 在工作中,如果你要是规定几个类必须有一样的方法.鸭子类型: 它看着像鸭子,那么他就是鸭子.

    python中好多不同类但同名的方法不是强制规定,而是约定俗成,像上面这三种类,都同样据有index方法,而且功能相似,
    则 他们三个互称为鸭子.

    如下示例:

    # str  list  tuple
    str.index()
    s1 = 'alex'
    class Str:
        def index(self):
            pass
    
    class List:
        def index(self):
            pass
    
    class tuple:
        def index(self):
            pass

    3.封装

    封装就是将一些属性或者方法(有用的信息)放置在一个空间中.

    1)广义的封装,指对象的封装.

    class Person:
        def __init__(self,name,age):
            self.name = name
            self.age = age
    p1 = Person('oldboy',1000)
    p2 = Person('alex',10000)
    print(p1.name)
    print(p2.name)

    2)私有的封装

    对于私有成员来说,他加载到内存时,都会加上_类名__变量名,所以你在类的外部,或者派生类中都不可访问.

    为什么设置私有成员?
    答: 有些变量,方法,属性,只在类内部进行使用即可,不便于(不允许)类外部或者派生类去调用.

    私有成员主要有三个,分别是:私有属性,私有字段,私有方法.

    这些私有成员的特点就是类外部不能访问,派生类不能访问,只能在类内部访问.

    如下示例:

    # 私有字段
    class A :
        num = 1
        __num1 = 2
        def fun(self):
            print(self.__num1)
    a1 = A()
    # print(a1.__num1)
    a1.fun()

    #这个在执行结果是2,如果把注释取消,会报错.

     这个原理是:当初始化类时,会把类中的__num这种带__的内部变量,自动在内存中存为_A__num的变量.

    所以也可以通过

    print(a1._A__num1)
    来打印的.

    如下示例:
    是私有对象属性的:
    #私有属性
    class A:
        def __init__(self,*args):
            self.name = args[0]
            self.sex = args[1]
            self.__age  = args[2]
        def fun(self):
            print(self.__age)
    a1 = A("alex","",18)
    # print(a1.__age)
    a1.fun()

    私有方法示例:
    class A :
        def fun(self):
            self.__fun1()
        def __fun1(self):
            print("111")
    a1 = A()
    # a1.__fun1()
    a1.fun()

    两个经典的面试题:

    class A:
        def __init__(self):
            self.__func()
        def __func(self):
            print('IN    A')
    class B(A):
        def __func(self):
            print('IN     B')
    b1 = B()
    
    #问题:初始化A后,打印的是什么?解释一下原理

    解答:

    这个最后打印的是IN A,原因是初始化对像的时候执行的是init函数,B对象中是没有的,只能去A中找,A里面是找到的,所以传入b1的对像到self里面,self执行的是.self.__fun()

    这个如上面所说,__fun()一开始被类初始化为_A__fun()这个变量了,所以找的是b1_A__fun()这个变量,然后开始从B中找,没有,在A中找到了,所有执行A中的函数.

    变种问题:

    class A:
        def __init__(self):
            self.func()
        def func(self):
            print('IN    A')
    class B(A):
        def func(self):
            print('IN     B')
    b1 = B()
    # print(b1.name)
    # print(b1.func)
    print(b1.func)
    print(b1.func())

    这个结果是IN B,同理因为B中没有init,所以到A中执行,A中执行后需要执行b1.fun(),,然后同理先在B()里面找到了,所以这个先在B里面找到的.

    类的结构:

    class Person:
        mind = '有思想...'  # 第一部分:所有的公有静态变量,公有静态字段
        __level = '高等动物'  # 第一部分:私有静态变量,私有静态字段
        def __init__(self,name,age,sex): # 构造方法  # 第二部分 动态方法,方法(函数)
            self.name = name   # 公有对象属性
            self.age = age
            self.__sex = sex  # 私有对象属性
        def func(self):   # 第二部分:普通方法
            print(666)
        def __func1(self):  # 第二部分:私有方法
            print(777)
    
        @staticmethod  #  静态方法
        def f2():pass
    
        @classmethod  # 类方法
        def f2(self): pass
    
        @property    # 属性
        def hex(self):pass

      

  • 相关阅读:
    Linux下端口被占用确认
    Debuggex – 超好用的正则表达式可视化调试工具
    URL最大长度
    无需重启 修改计算机名直接生效
    UDP穿越NAT原理(p2p)
    gdb中信号
    锁 (读写锁优先级 写饥饿) (锁竞争引发的高系统调用)
    Loopback接口用途---用作管理地址。
    C/C++调试:gdbserver的简单使用
    总结一下NDK crash排查步骤
  • 原文地址:https://www.cnblogs.com/ahliucong/p/9254286.html
Copyright © 2020-2023  润新知