引言
虽然,截止目前从来没有系统性地讲述面向对象的内容,但是阅读过前面文章的童鞋,关于Python中的面向对象应该有如下观念了:
1、Python中一切皆对象,对象有三个核心内容:id、类型、值。
2、Python中的函数和类也是一等公民。
3、面向过程和面向对象只是不同的编程范式,各自有擅长的使用场景,没有绝对的好坏之分。
其实,基于前面的3点,我们还可以有如下推导:
4、Python中一切皆是一等公民。
5、一切皆对象,则Python中的赋值皆为引用赋值,赋值的结果表现不同,更多的是源于所引用对象的可变、不可变。
6、每个对象都有一个所属类型,这个类型是创建对象的模板、机制,本身也是对象。
关于对象的类型,我们可以将类型简称为“类”。除了整数、浮点数、字符串、列表、元祖、字典等内置类型外,我们还可以根据需要自定义各种类型。相较于其他编程语言,Python中的面向对象实现得更加彻底。从而可以让我们定义出不逊色于内置类型的各种类型,实现“万类霜天竞自由”。
定义类(class)
在Python自定义类的语法很简单,关键点在于真正定义之前的面向对象的分析与设计,也就是所谓的OOA和OOD。
大体来说,有这么几个步骤:
1、分析业务需求,从需求中梳理出关键的业务实体,进而定义出实体的概念模型,通常来说,每一个业务实体对应一个类。
2、进一步细化每一个业务实体,梳理出实体中关键的业务属性,一般是静态的特征,这些就是类定义中的属性的分析了,这一步定义出了类的逻辑模型。
3、分析每一个业务实体需要具备的功能或者涉及到的操作,也就是梳理出类应当具备的方法,也就是类的动态行为特征。
可以对应到数据库的建模中,第一步梳理出业务实体类,也就是一个常规的关系表,这时只是需要有一个表的概念;第二步梳理出业务实体类中的静态属性,也就是表中应该具有的字段定义了;第三步是对表中的数据需要进行的增删改查的操作的定义了。
初学者不太理解没关系,可以先跳过,接下来进入主题部分,类的定义语法。
还是拿上一篇的需求来进行说明:
假如我们有一个研发团队,我们需要把每个打工人的数据存储下来,后续根据工作表现,进行入转调离的管理。
首先,我们这个需求的实体,主要就是打工人,假如我们的类名就是实体的拼音全拼:DaGongRen。
其次,我们来分析一下打工人应该有哪些属性特征,稍微简化一下,应该有工号、姓名、性别、年龄、薪资、状态。
然后,是打工人的动态行为,最主要的行为是打工,然后是加薪,还有离职。
直接看代码:
class DaGongRen:
def __init__(self, no, name, age, gender, salary=10000, status='试用'):
self.no = no
self.name = name
self.age = age
self.gender = gender
self.salary = salary
self.status = status
def work(self):
print(f"工号:{self.no}的员工【{self.name}】在努力工作中")
def salary_increase(self, inc=0):
self.salary += inc
def change_status(self, status):
self.status = status
简单解释一下,我们在__init__方法中定义了类的相关对象属性,分别是工号、姓名、性别、年龄、薪资、状态。
__init__方法,可以理解为是固定写法,是用来进行对象的初始化的。
此外,还有work方法、salary_increase方法和change_status方法。
这些方面的第一个参数,习惯性写作self,表示要初始化或者操作的对象的引用,当然也可以改为其他名字,只是通常没有必要改动。
但是,这些代码执行完成,只是定义了一个打工人的类,不会有任何输出。
需要特别说明的是,相关的定义语法先这样记忆并使用,能进行解释的,后续的文章中会进行一定的展开,不能解释的,规定就是规定,没有必要去深究。
接下里,我们看怎么使用这个类。
对象实例化
我们前面提到过,类定义了对象的创建机制,也就是类的模板,我们通过类可以创建具体的对象,这个操作,也叫做对象实例化。
对象的实例化的语法很简单:
class DaGongRen:
def __init__(self, no, name, age, gender, salary=10000, status='试用'):
self.no = no
self.name = name
self.age = age
self.gender = gender
self.salary = salary
self.status = status
print(self)
print('初始化完成')
def work(self):
print(f"工号:{self.no}的员工【{self.name}】在努力工作中")
def salary_increase(self, inc=0):
self.salary += inc
def change_status(self, status):
self.status = status
if __name__ == '__main__':
dgr = DaGongRen('D001', '张三', 34, '男')
print(dgr)
print(dgr.name)
dgr.work()
执行结果:
简单解释一下,在Python中类也是一个callable对象,是可以类似于函数的()调用的,而实际上会将()中的参数传递给__init__方法,由于第一个参数self是不需要我们自行传递的,Python解释器会完成对象的引用到self参数的传递。我们可以通过__init__方法中的输出,跟对象引用的输出,看到这一点。
所以,实例化时()中的参数是传递给__init__方法的第二个及之后的参数的。
通过实例化,我们就获取了一个对象实例。我们可以通过.的操作,来访问对象的属性及方法。