006、面向对象(三)、继承、私有属性

 

面向对象(三)、继承、私有属性

  1、私有属性

    类属性、方法 私有:

    a、浅度私有: _属性  、_方法  ;可以通过  实例._属性  访问,但是设计这个私有属性的本意是别访问我 ;

    b、深度私有:__属性 、__方法  ;不可以通过   实例._属性  访问,但是可以通过   f._Father__private_money   访问 ; 

 

 

    模块私有:

     c、私有化属性、私有化方法 同样适合在  .py 模块中 ,意思是一样的 ;

    不管是   浅度私有   还是   深度私有 ,设计的本意是   类 / 模块  外面   别访问该属性 ;仅限于  类 / 模块 内部访问 ;

    d、类也可以做成 私有类  class  _Money()  、class  __PrivateMoney  ,使用方法相同  ;

    e、当模块 、类 要实现一个大功能,而这个大功能由很多个内部小功能组成的,这时 这些小功能可以定义为  私有的 ,不需要被外包访问 ;

 

  示例代码如下:

# 模块 浅度私有
_hello = 'world'


# 模块 浅度私有
def __hello():
    print('我不想其他的模块访问')


class Father():

    def __init__(self, name, money, private_money):
        self.name = name
        self._money = money                     # 零花钱
        self.__private_money = private_money    # 私房钱

    # 类内部可以访问私有属性
    def show_money(self):
        print('零花钱:{0}'.format(self._money))
        self.__show_private_money()

    # 类内部可以访问私有方法
    def __show_private_money(self):
        print('私房钱:{0}'.format(self.__private_money))


f = Father('sky', 1000, 500)
f.show_money()

# 浅度私有:可以通过 实例._属性 访问,但是设计这个私有属性的本意是别访问我 ;
print(f._money)

# 深度私有:不可以通过 实例._属性 访问,但是可以通过 实例.类.__属性 访问 ;
# print(dir(f))
print(f._Father__private_money)
# print(f.__private_money)    # 报错: AttributeError: 'Father' object has no attribute '__private_money'
View Code

  执行结果如下:

零花钱:1000
私房钱:500
1000
500

Process finished with exit code 0
View Code

 

python 中 __all__ 的使用:https://www.cnblogs.com/wxlog/p/10566628.html

  python模块中的__all__,用于模块导入时限制,如:from module import *

  此时被导入模块若定义了__all__属性,则只有__all__内指定的属性、方法、类可被导入;若没定义,则导入模块内的所有公有属性,方法和类。

 

 

 

  2、继承  class B(父类)

    a、浅度私有: _属性  、_方法  ;可以被继承,但不建议使用 ;

    b、深度私有:__属性 、__方法  ;不可以被继承 ;

    c、python 可以多继承  (三姓家奴,哈哈,不会被重用。)   很少用 ;

    d、子类方法 与 父类方法 同名时,重写方法 ;重写时去copy父类的函数和参数 ;

    e、如果要调用父类的  同名方法, 用  super().方法()  ;

    f、由于python有  *args  、 *kwargs  不定长参数,参数类型随便传什么都可以,所以没有 重载

    g、python不支持多态,或者说 python本来就是多态语言。引入了 鸭子类型 的概念  ;

 

  示例代码如下:

# 模块 浅度私有
def __hello():
    print('我不想其他的模块访问')


class Father():

    def __init__(self, name, money, private_money):
        self.name = name
        self._money = money                     # 零花钱
        self.__private_money = private_money    # 私房钱

    def rest(self):
        print('{0} 抽支烟'.format(self.name))


class Son(Father):

    # 重写 have_rest 方法
    def rest(self):
        print('{0} 玩一把游戏'.format(self.name))

    # 用 super().父类方法() 调用父类的属性
    def have_rest(self):
        super().rest()


s = Son('袁克定', 2000, 200)
# print(s._money)       # 浅度私有: _属性  、_方法  ;可以被继承,但不建议使用 ;

# AttributeError: 'Son' object has no attribute '__private_money'
# 深度私有:__属性 、__方法  ;不可以被继承 ;
# print(s.__private_money)
s.rest()
s.have_rest()
View Code

  执行结果如下:

D:\SkyWorkSpace\WorkSpace\Pytest\Temp\day10\venv\Scripts\python.exe D:/SkyWorkSpace/WorkSpace/Pytest/Temp/day10/test_01/test_05.py
袁克定 玩一把游戏
袁克定 抽支烟

Process finished with exit code 0
View Code

 

 

用子类对象调用父类已被覆盖的方法

class Parent:  # 定义父类
    def my_method(self):
        print('调用父类方法')


class Child(Parent):  # 定义子类
    def my_method(self):
        print('调用子类方法')


c = Child()  # 子类实例
c.my_method()  # 子类调用重写方法
super(Child, c).my_method()  # 用子类对象调用父类已被覆盖的方法

执行结果如下:

D:\SkyWorkSpace\WorkSpace\Web_AutoTest\Temp\day01\venv\Scripts\python.exe D:/SkyWorkSpace/WorkSpace/Web_AutoTest/Temp/day01/ch_003/test.py
调用子类方法
调用父类方法

Process finished with exit code 0

 

posted @ 2021-08-01 22:40  空-山-新-雨  阅读(78)  评论(0编辑  收藏  举报