python面向对象之封装

面向对象(object oriented)

对象就是将属性与功能封装在一起,实际上对象本身的概念就体现了封装

面向对象的封装有三种方式:

  • public
    公开:不封装,对外公开
  • protected
    受保护:对外不公开,但对朋友(friend)或者子类(形象的说法是“儿子”,但我不知道为什么大家 不说“女儿”,就像“parent”本来是“父母”的意思,但中文都是叫“父类”)公开
  • private
    私有化:这种封装对谁都不公开

属性和功能的隐藏

也叫私有变量私有方法

python在定义对象的时候能够隐藏属性和功能,被隐藏的功能在定义之后无法从外部获得

class A:
    __N=0  # 变形为_A__N,成为隐藏属性

    def __init__(self): # 定义函数时,会检测函数语法,所以__开头的属性也会变形
        self.__x=10  # 变形为self._A__x

    def __f1(self):  # 变形为_A__f1
        print('__f1 run')

    def f2(self):  # 定义函数时,会检测函数语法,所以__开头的属性也会变形
        self.__f1()  # 变形为self._A__f1()

print(A.__N) # 报错AttributeError:类Foo没有属性__N
obj = A()
print(obj.__x) # 报错AttributeError:对象obj没有属性__x
print(obj._A__N)  # 能够直接进行访问
'''
隐藏属性和隐藏函数介绍:
	隐藏属性实际上是在函数定义时完成的变形
	函数定义时会将定义时前面带有双下划线的属性和函数包装成“_类名__属性”的形式
	这种做法在一定程度上隐藏了属性和函数,在外部无法直接访问,但是一旦掌握原理,通过“_类名__属性”还是能够访问到的
	实际上在应用时这是一种约定俗成,放你看到下划线定义隐藏属性和函数的时候,记得不要将其进行更改	
'''
# 隐藏的目的实际上是为了使用
class Teacher:
     def __init__(self,name,age):  # 将名字和年纪都隐藏起来
         self.__name=name
         self.__age=age
     def tell_info(self):  # 对外提供访问老师信息的接口
         print('姓名:%s,年龄:%s' %(self.__name,self.__age))
     def set_info(self,name,age):  # 对外提供设置老师信息的接口
         if not isinstance(name,str):  # 判断变量name的类型
             raise TypeError('姓名必须是字符串类型')
         if not isinstance(age,int):
             raise TypeError('年龄必须是整型')
         self.__name=name
         self.__age=age
 
t=Teacher('lilei',18)
t.set_info(‘LiLei','19')  # 年龄不为整型,抛出异常
# Traceback (most recent call last):

TypeError: 年龄必须是整型
t.set_info('LiLi',19)  # 名字为字符串类型,年龄为整形,可以正常设置
t.tell_info() # 查看老师的信息
# 姓名:LiLei,年龄:19

@property

@property是一个装饰器,作用是将一些函数功能封装成属性,这种需求我们经常遇到,比如说圆的面积或者周长,我们得到的数据可能是一个半径,但是需要的面积,并且计算的方法是固定的,这时将函数封装成属性更加的方便并且不易被篡改,这体现的也是封装的思想

Class Circle:
	def __init__(self,r):
		self.r=r
	@property
	def square(self):
		self.square=pi*self.r*self.r
c1=Circle(3)
print(c1.square)  # 直接返回面积

# property函数还提供了修改和删除的方法
class Foo:
    def __init__(self,val):
        self.__NAME=val  # 将属性隐藏起来
    @property
    def name(self):
        return self.__NAME
    @name.setter
    def name(self,value):
        if not isinstance(value,str):  #类型检查
            raise TypeError('%s must be str' %value)
        else:
        	self.__NAME=value
    @name.deleter
    def name(self):
        raise PermissionError('Do not delete')
f=Foo('lili') # 实例化
f.name# 查看对象的属性
f.name='LiLi'  # 触发name.setter装饰器对应的函数name(f,’LiLi')
del f.name  # 触发name.deleter对应的函数name(f),抛出异常PermissionError

类方法@classmethod

类方法是一个非常典型的绑定方法,将方法绑定给类

'''
类方法的作用是将某一个方法绑定给类
类属性的时候是直接在类下面创建属性
像下面的role属性,类属性与其类似
class Classmethod_Demo():
    role = 'dog'
    @classmethod
    def func(cls):
        print(cls.role)

Classmethod_Demo.func()  # 类方法可以由直接进行调用
'''

绑定到类的方法就是类专用的,虽然对象也可以调用,但是自动传入的第一个参数仍然是类本身,也就是说这种调用没有意义

静态方法@staticmethod

静态方法是一种非绑定方法,该方法不与类或对象绑定,类与对象都可以来调用它,但它就是一个普通函数而已,因而没有自动传值那么一说

'''
静态方法是直接在类中定义一个方法,这个方法谁都可以使用
class Staticmethod_Demo():
    role = 'dog'
    @staticmethod
    def func():
        print("当普通方法用")
Staticmethod_Demo.func()

静态方法主要是用来存放逻辑性的代码,主要是一些逻辑属于类,但是和类本身没有交互
即在静态方法中,不会涉及到类中的方法和属性的操作
可以理解为,静态方法是个独立的、单纯的函数,它仅仅托管于某个类的名称空间中,便于使用和维护
'''
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值