面向对象-封装实现属性隐藏

封装原理与特性

隐藏属性:在变量或函数前面加__符号

class A:
    __x=1
    def __init__(self,name):
        self.__name=name
    def __foo(self):
        print('run foo')
print(A.__x)

print(A.__dict__)

在类定义阶段就,已经改名字。即检测语法的时候已经变形。

在类的内部可以直接调用

class A:
    __x=1
    def __init__(self,name):
        self.__name=name
    def __foo(self):
        print('run foo')
    def bar(self):
        self.__foo()
        print('from bar')
a=A('ya')
a.bar()

 正常情况下,子类可以重写父类方法

class Foo:
    def func(self):
        print("from foo")
class Bar(Foo):
    def func(self):
        print('from foo')
b=Bar()
b.func()

但是父类方法隐藏后,子类无法重写父类方法

class Foo:
    def __func(self):
        print("from foo")
class Bar(Foo):
    def __func(self):
        print('from foo')
b=Bar()
b.func()

变形特点

  • 在类的外部无法直接通过obj.__AttrName来访问
  • 在类的内部可以直接使用obj.__AttrName来访问
  • 子类无法重写父类方法,即子类无法覆盖父类__开头的属性

变形注意的问题:

  • 这种隐藏不是真正的隐藏
  • 变形在类定义阶段发生,定义后再给类添加隐藏属性,则无法达到‘隐藏’效果
  • 在继承中,如果父类不想子类重写方法,可用__设置称私有的,使其无法修改

封装的意义

封装数据属性:明确区分内外,在内部定义接口,使其外部间接访问,也可定义修改接口,可以在接口上添加逻辑,进行控制。

class People:
    def __init__(self,name,age):
        self.__name=name
        self.__age=age
    def tell_info(self):
        print('Name:<%s> Age<%s>' % (self.__name,self.__age))
p=People('ya',18)
p.tell_info()

class People:
    def __init__(self,name,age):
        self.__name=name
        self.__age=age
    def tell_info(self):
        print('Name:<%s> Age<%s>' % (self.__name,self.__age))
    def set_info(self,name,age):
        if not isinstance(name,str):
            print('名字必须是字符类型')
            return
        if not isinstance(age,int):
            print('年龄必须为数字')
            return
        self.__name=name
        self.__age=age
p=People('ya',18)
p.tell_info()
p.set_info('Hyaya','19')
p.tell_info()

封装方法:隔离复杂度

class ATM:
    def __card(self):
        print('插卡')
    def __auth(self):
        print('用户认证')
    def __input(self):
        print('输入取款金额')
    def __print_bill(self):
        print('打印账单')
    def __take_money(self):
        print('取款')

    def withdraw(self):
        self.__card()
        self.__auth()
        self.__input()
        self.__print_bill()
        self.__take_money()
a=ATM()
a.withdraw()

类外部用户无需单独一步一步执行__方法,只需调用withdraw()方法即可

封装与扩展

class Room:
    def __init__(self,name,owner,height,weight,length):
        self.name=name
        self.owner=owner
        #将长宽高设置为隐藏
        self.__height=height
        self.__weight=weight
        self.__length=length
    def tell_area(self):
        return self.__weight * self.__length
r=Room('卫生间','xxx',10,10,10)
print(r.tell_area())

用户可以随意修改tell_area()方法,对于用户的调用,无需干涉。

property的使用

把通过计算才能获得值得方法封装称属性方式,调用无需添加()符号

装饰后,调用数据属性的方式调用方法属性,但是不可直接像数据属性一样赋值

class People:
    def __init__(self,name,weight,height):
        self.name=name
        self.weight=weight
        self.height=height
    @property
    def bmi(self):
        return self.weight / (self.height ** 2)

p=People('egon',80,1.6)
print(p.bmi)

p=People('egon',80,1.6)
p.bmi=22
print(p.bmi)

对方法属性再次控制

class People:
    def __init__(self,name):
        self.__name=name
    @property
    def name(self):
        return self.__name
    @name.setter
    def name(self,val):
        if not isinstance(val,str):
            print(("名字必须为字符串"))
            return
        self.__name=val
    @name.deleter
    def name(self):
        print('名字属性不让删除')
p=People('ya')
p.name="YA"
print(p.name)
del p.name

 

转载于:https://www.cnblogs.com/yaya625202/p/8879534.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值