面向对象的三大特征:封装,继承,多态
含义理解:
封装:把内部实现的过程封装起来,对用户只保留接口
主要目的:保护数据,防止出现不合法的数据
继承:来源于生活,继承父类中的特征和方法。
注意事项:必须存在 is …a的关系才可以使用继承。比如:学生是一个人
多态:必须建立在继承的基础之上,可以简单理解为含有多个子类。
案例一:封装代码实现
方式一:属性私有化,set赋值,get 获取值
class Person(object):
#属性私有化
__name = ''
#设置name属性的值
def setName(self, n):#传入一个参数,用来传递name的值
if n == '' or n == 'None':
self.__name = '鱿小鱼'
else:
self.__name = n
# get 获取值
def getName(self):
return self.__name
#创建一个实例化对象
mz = Person()
#赋值
mz.setName ('')
#获取
print(mz.getName())
返回结果:
方式二:装饰器 @property(翻译:属性)
class Person(object):
def __init__(self,name):
self.__name=name
@property #相当于方法一种的get
def name(self):
return self.__name
@name.setter #相当于方法一种的set
def name(self,value):
self.__name=value
mz=Person('鱿小鱼')
print(mz.name)
返回结果:
其实樱子写的这种只是简单的。大家可以ctrl+B查找一下源代码(樱子也是一言不合就ctrlB啊 (/ω\)(/ω\),但是说实话源代码真的是有很强的威慑力的,而且他也比较严谨)
这种装饰器方法有一个小细节大家需要注意一下。
这三个地方的名字是一样的。原因是:被property装饰过的函数名会被当做对象的属性名去用。比如:mz.name,该函数的名字被伪装成了属性名,当mz.name被调用的时候,首先从mz这个对象自己这找一个name属性,自己没有的话就跑到父类(object)那里去找,父类没有原始的name属性,但是有一个被property装饰器修饰的name属性,找到后就触动name函数开始运行,得到一个返回值,这个self.__name中存放的真正的函数值,函数值就返回后给了mz.name。
如果大家仔细观察的话,不难看出,源码中还添加了一个deleter装饰器。
樱子也试了,但是结合到一起有点复杂,而且他会报一种Attribute属性错误。大家如果感兴趣的话,我可以给大家解释一下。
class Person(object):
def __init__(self,name):
self.__name=name
@property
def name(self):
return self.__name
@name.setter
def name(self,value):
self.__name=value
@name.deleter
def name(self):
del self.__name
mz=Person('鱿小鱼')
mz.name='樱子'
del mz.name
print(mz.name)
在上面的代码中,
首先:被property这个装饰器装饰过的函数名会被伪装成对象的函数名去调用。
其次:当mz.name='樱子’的时候会触发name.setter这个装饰器的执行,这时会将‘樱子’赋值给value,value直接再将值赋值给self.__name,从而实现属性的修改。
接着:当del mz.name的时候,会触发name.deleter的操作执行,从而将name属性值给删除掉。
最后,当查找mz.name的时候会再次触发property这个装饰器运行,然而self.__name已经被删除,所以会报Attribute属性错误。
大家可以尝试着做一下练习哦!
封装题练习:
Employer类, 工号,姓名,性别,年龄,职位,工资
工号,姓名,不能为空
性别:男或者女
年龄:18-65岁
职位:员工和经理
工资:5000以上
(答案在下一章,敬请期待哦~~~~~~~~~~~~)