【python】类的封装、多态

本文介绍了Python面向对象编程中的类方法封装,包括实例方法、私有属性的封装以及使用@property装饰器进行属性封装。通过具体案例展示了如何创建Person类和Bank类,实现体重管理和银行账户余额的增减操作,并确保数据的安全性和有效性。同时,讨论了通过setter和getter方法以及@property装饰器如何优雅地访问和修改私有属性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 类的封装

1.1 实例方法来实现共同的需求(业务) --实例方法的封装

1-类中实例方法的封装'''
# 案例需求:
# 小明体重75.0公斤,每次跑步会减肥0.5公斤,每次吃东西体重会增加1公斤
# 小美的体重是45.0公斤,每次跑步会减肥0.5公斤,每次吃东西体重会增加1公斤

# 解题的思路
'''类(类名,属性,方法)
类名:Person
属性:
    姓名-name
    体重-weight
功能: 
    跑步-run()
    吃东西-eat()
class Person():
    def __init__(self,name,weight):
        self.name = name
        self.weight = weight
        print('姓名:{},体重:{}'.format(self.name,self.weight))

    def run(self):
        self.weight -= 0.5
        print('姓名:{},跑步后,体重:{}'.format(self.name,self.weight))

    def eat(self):
        self.weight += 1
        print('姓名:{},吃东西后,体重:{}'.format(self.name, self.weight))

# 对象
xiaoming = Person('小明',75)
xiaomei = Person('小美',45)
xiaoming.run()
xiaomei.eat()

1.2 类中私有属性的封装

访问接口一般是由set()/get()方法来表示,
get()方法是提供接口的访问通道,
而set()方法是提供接口的修改通道。
# 案例需求:设计一个银行类,类中有姓名和金额,为了隐藏细节,不能让用户随便修改金额;
# 如果确实要修改金额,则要提供访问访问接口,然后还要避免在操作类的 对象过程中的误操作,
# 比如修改金额传入非法数据,为了保证数据的有效性,要对传入的数据进行判断。

# 解题的思路
类(类名,属性,方法)
类名:Bank
属性:
    姓名 - name
    金额 - money
功能: 
    查询 - check()
    取钱 -
    存钱 -
    ..
class Bank():
    def __init__(self,name,money):
        self.name = name
        self.__money = money
        print('姓名:{},余额:{}'.format(self.name,self.__money))

    # 给外部访问提供一个接口
    def get_money(self):
        # 查询余额
        # return self.__money
        print('当前余额{}'.format(self.__money))

    def set_money(self,m):
        # m是否是一个数值;m>0  存钱的操作  m<0 取钱的操作  m=0 不做操作
        # 取钱
        if isinstance(m,int) or isinstance(m,float):
            if m > 0:
                self.__money += m
                print('存钱操作,存钱后余额:{}'.format(self.__money))
            elif m < 0 :
                if  (abs(m) <=  self.__money):
                    self.__money -= abs(m)
                    print('取钱操作,取钱后余额:{}'.format(self.__money))
                else:
                    print('余额不足,无法操作~~')
            else:
                print('输入金额为0,不做任何操作~~')

        else:
            print('非法操作,请重新输入~~')

zs = Bank('zs',1000)

zs.get_money()
zs.set_money(100)
zs.set_money(-2000)

# 问题:改变了我们调用的方式
# zs.__money    --》 zs.get_money()
# zs.__money = 新值  --》 zs.set_money(100)

# 既要有访问和修改的权限,又不要不改变调用的方式
zs.money
zs.money = 100

1.3 使用装饰器@property(属性方法) 私有属性的封装

使用装饰器@property(属性方法) 私有属性的封装    
封装属性时,装饰器的使用
    装饰器写在get_xxx()函数名的上一行,在get_xxx()函数命名直接以属性名来命名,不需要加上set/get。
    在get方法加上@property,方法名与私有属性名一致
    在set方法上方加上@xxx.setter,方法名与私有属性名一致,其中xxx与方法名一致

使用装饰器的方法调用
    查看:对象名.方法名   
    修改:对象名.方法名=新值 

# 案例需求:设计一个银行类,类中有姓名和金额,为了隐藏细节,不能让用户随便修改金额;
# 如果确实要修改金额,则要提供访问访问接口,然后还要避免在操作类的 对象过程中的误操作,
# 比如修改金额传入非法数据,为了保证数据的有效性,要对传入的数据进行判断。


class Bank():
    def __init__(self,name,money):
        self.name = name
        self.__money = money
        print('姓名:{},余额:{}'.format(self.name,self.__money))

    # 给外部访问提供一个接口
    @property
    def money(self): #方法名与属性名一致,但是不要加两个下划线
        # 查询余额
        # return self.__money
        print('当前余额{}'.format(self.__money))

    @money.setter
    def money(self,m): #方法名与属性名一致,但是不要加两个下划线
        # m是否是一个数值;m>0  存钱的操作  m<0 取钱的操作  m=0 不做操作
        # 取钱
        if isinstance(m,int) or isinstance(m,float):
            if m > 0:
                self.__money += m
                print('存钱操作,存钱后余额:{}'.format(self.__money))
            elif m < 0 :
                if  (abs(m) <=  self.__money):
                    self.__money -= abs(m)
                    print('取钱操作,取钱后余额:{}'.format(self.__money))
                else:
                    print('余额不足,无法操作~~')
            else:
                print('输入金额为0,不做任何操作~~')

        else:
            print('非法操作,请重新输入~~')

zs = Bank('zs',1000)

zs.money
zs.money = 100
zs.money = -500

 

 

 

Python中,封装、继承和多态是面向对象编程(OOP)的三大特性,它们一起构成了面向对象设计的核心。 1. **封装**:这是一种数据隐藏的方式,将数据(变量)和操作这些数据的方法组合在一起形成一个独立的对象。通过`private`前缀(虽然Python没有严格的私有属性机制,但通常用下划线`_`代替),可以限制直接访问数据,提供公共接口供外部操作。 ```python class Circle: def __init__(self, radius): self.__radius = radius def get_radius(self): # 提供获取半径的途径 return self.__radius def set_radius(self, new_radius): if new_radius > 0: self.__radius = new_radius else: print("Radius cannot be negative.") # 使用封装的例子 circle = Circle(5) print(circle.get_radius()) # 输出5 ``` 2. **继承**:一个可以从另一个派生出来,继承其属性和方法。例如,创建一个动物,然后派生出更具体的狗和猫: ```python class Animal: def __init__(self, name): self.name = name def speak(self): pass # 父方法,留空等待子实现 class Dog(Animal): def speak(self): return "Woof!" class Cat(Animal): def speak(self): return "Meow!" dog = Dog("Rex") cat = Cat("Luna") print(dog.speak(), cat.speak()) # 输出"Woof!" "Meow!" ``` 3. **多态**:在Python中,多态允许使用父引用去操作子实例,实现了“同一种行为在不同型的对象上产生不同的效果”。如上面的Dog和Cat例子,虽然都是Animal的子,但`speak`方法的具体实现各不相同。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值