前言
在前面,我用了3篇文章解释python的面向对象:
面向对象:从代码复用开始
面向对象:设置对象属性
类和对象的名称空间
本篇是第4篇,用一个完整的示例来解释面向对象的一些细节。
例子的模型是父类Employe和子类Manager,从类的定义开始,一步步完善直到类变得完整。
定义Person类
现在,假设Employe类有3个属性:名字name、职称job和月薪水pay。
定义这个类:
class Employe():
def __init__(self, name, job=None, pay=0):
self.name = name
self.job = job
self.pay = pay
这里为__init__()的job参数提供了默认值:None,表示这个员工目前没有职称。对于没有职称的人,pay当然也应该是0。这样创建Employe对象的时候,可以只给参数name。
例如:
if __name__ == "__main__":
longshuai = Employe("Ma Longshuai")
xiaofang = Employe("Gao Xiaofang", job="accountant", pay=15000)
上面的if判断表示这个py文件如果当作可执行程序而不是模块,则执行if内的语句,如果是以模块的方式导入这个文件,则if内的语句不执行。这种用法在测试模块代码的时候非常方便。
运行该py文件,得到结果:<__main__.employe object at>
添加方法
每个Employe对象的name属性由姓、名组成,中间空格分隔,现在想取出每个对象的名。对于普通的姓 名字符串,可以使用字符串工具的split()函数来处理。
例如:
>>> name = "Ma Longshuai"
>>> name.split()[-1]'Longshuai'
于是可以在longshuai和xiaofang这两个Employe对象上:
print(longshuai.name.split()[-1])
print(xiaofang.name.split()[-1])
结果:Longshuai
Xiaofang
与之类似的,如果想要为员工按10%加薪水,可以在每个Employe对象上:
xiaofang.pay *= 1.1
print(xiaofang.pay)
无论是截取name的名部分,还是加薪水的操作,都是Employe共用的,每个员工都可以这样来操作。所以,更合理的方式是将它们定义为类的方法,以便后续的代码复用:
class Employe():
def __init__(self, name, job=None, pay=0):
self.name = name
self.job = job
self.pay = pay
def lastName(self):
return self.name.split()[-1]
def giveRaise(self, percent):
self.pay = int(self.pay * (1 + percent))
if __name__ == "__main__":
longshuai = Employe("Ma Longshuai")