• python----面对对象三大特征2


    多态

      什么是多态?多态指的是一类事物有多种形态,例如一个动物类,狗和猫都通过继承动物类来得来,这样我们可以将狗、猫称作动物类的另一种形态。

      在java中也存在多态,java中的多态是用来解决在一个函数中如果接受2个以上类型的参数,那么这些类型都应该继承同一个类,这个类是所有子类的对象的类型,在java中函数是需要指定传入的类型的,如果传入的参数类型不对应则就会报错:

      那么java中是如何解决这个问题的呢,就是用了多态:class Payment:      #父类,支付类

    pass
    
    class Apay(Payment):  #子类,苹果支付
        def pay(self):
            pass
    
    class Alipay(Payment):  #子类,阿里支付
        def pay(self):
            pass
    apay = Apay()
    alipay = Alipay()
    def pay(obj):   obj.pay
    pay(apay)  #传入apay类
    pay(alipay)  #传入alipay类

      可以看出pay()接受了2个类型的参数,如果在java中是会报错的,那么如何解决这个问题呢。我们可以把pay()接受的参数类型定位payment类,然后所有的传入的参数都是此类的子类,这样参数类型就同一了。

      而在python中大家发现我们在传参数时并没有类型限制,这是为什么呢,大家知道python3中 全都是新式类,而新式类都自动继承了一个object一个类。所以:

    在python中:函数的参数不需要指定数据类型,所以我们也不需要通过继承的形式来统一一组类的类型,
    换句话说 所有的对象其实都是object类型,所以在python当中其实处处是多态。

    鸭子类型:

      Python崇尚鸭子类型,即‘如果看起来像、叫声像而且走起路来像鸭子,那么它就是鸭子’

    python程序员通常根据这种行为来编写程序。例如,如果想编写现有对象的自定义版本,可以继承该对象

    也可以创建一个外观和行为像,但与它无任何关系的全新对象,后者通常用于保存程序组件的松耦合度。

    利用标准库中定义的各种‘与文件类似’的对象,尽管这些对象的工作方式像文件,但他们没有继承内置文件对象的

    封装:

      什么是封装,封装就是将对象的某些属性和方法隐藏起来,只能在自己的内部调用,对外只能提供公共的访问方式。

    【好处】 

    1. 将变化隔离; 

    2. 便于使用;

    3. 提高复用性; 

    4. 提高安全性;

    【封装原则】

          1. 将不需要对外提供的内容都隐藏起来;

          2. 把属性都隐藏,提供公共方法对其访问。

    广义上的封装:

    class 类名:
        def 方法1(self):
            pass
    # 是为了只有这个类的对象才能使用定义在类中的方法

    狭义的封装:

      在python中用双下划线开头的方式将属性隐藏起来(设置成私有的)

    私有变量(属性)

    class Goods:
        
        __discount = 0
        print(__discount)
        
    print(Goods.__discount)  #报错提示AttributeError: type object 'Goods' has no attribute '__discount'
    print(Goods.__dict__)
    #运行结果:{'__module__': '__main__', '_Goods__discount': 0, '__dict__': <attribute '__dict__' of 'Goods' objects>, '__weakref__': <attribute '__weakref__' of 'Goods' objects>, '__doc__': None}

      可以看出在打印Goods属性的时候可以看到_Goods__discount': 0,而不是__discount,这是因为当定义一个--变量名时,python会将做一个变形变成_类名__变量的模式,这样对象.__变量名就找不到属性了,而在类内部__变量名还是可以找到,这也是print(__discount)运行的原因,因为在类中调用时会自定转化成_类名__变量。

    总结:

    1.类中定义的__x只能在内部使用,如self.__x,引用的就是变形的结果

    2.这种变形其实正是针对外部的变形,在外部是无法通过__x这个名字访问到的。

    3.在子类定义的__x不会覆盖在父类定义的__x,因为子类中变形成了:_子类名__x,而父类中变形成了:_父类名__x,即双下滑线开头的属性在继承给子类时,子类是无法覆盖的。

    私有方法:

      既然能将属性私有,当然也可将类的方法私有,跟私有属性一样,就是在方法前面加__:

    class Goods:
        __discount = 0.7
        def __init__(self,name,price):
            self.name = name
            self.price = price
        def __set_discount(self,num):
            self.__discount = num

    上面这个例子是一个商品类,有两个属性,一个名称还有个价格,是私用属性,外部访问不到,然后还有个私用方法,所以一般别人不知道根本修改不了折扣,也不知道商品的价格

    # 类中的私有成员:
        # 私有的静态属性
        # 私有的对象属性
        # 私有的方法
    
    # 我为什么要定义一个私有变量呢:
        # 我不想让你看到这个值
        # 我不想让你修改这个值
        # 我想让你在修改这个值得时候有一些限制
        # 有些方法或者属性不希望被子类继承
    
    # 私有变量能不能在外部被定义???
    # class A :
    #     __country = 'China'  # 在类的内部会发生变形
    #     print(__country)      # '_A__country'
    # print(A.__dict__)
    # A.__Language = 'Chinese'
    # print(A.__dict__)
    
    # 私有变量能不能被继承???
    # class A:
    #     __country = 'China'
    #     def __init__(self,name):
    #         self.__name = name  # '_A__name'
    #
    # class B(A):
    #     # print(__country)
    #     # NameError: name '_B__country' is not defined
    #     def get_name(self):
    #         return self.__name  # '_B__name'
    #
    # b = B('alex')
    # print(b.__dict__)
    
    # 广义上的封装 把属性函数都放到类里
    # 狭义上的封装 定义私有成员
    
    # 类中的私有成员:
        # 私有的静态属性
        # 私有的对象属性
        # 私有的方法
    
    # 我为什么要定义一个私有变量呢:
        # 我不想让你看到这个值
        # 我不想让你修改这个值
        # 我想让你在修改这个值得时候有一些限制 : 保证了数据的安全
        # 有些方法或者属性不希望被子类继承
  • 相关阅读:
    os 模块1
    除法
    python基础四(jsonossys andomstring模块、文件、函数)
    python基础三(集合、文件)
    linux下mysql安装
    linux下tomcat安装
    linux系统jdk安装
    python基础二(list,tuple元祖、dic字典,字符串)
    python基础一(安装、变量、循环、git)
    charles抓包
  • 原文地址:https://www.cnblogs.com/Kingfan1993/p/9554811.html
Copyright © 2020-2023  润新知