类
描述一类事物共有的数据和能做的事,用来制造具体的个体。
它是什么
类 是一份图纸。它说明这一类事物有哪些数据、能做哪些动作。按图纸可以造出许多 对象,每个对象有自己的一份数据,但共享同一套方法。没有对象,类只是说明书。只写出 class 而不去调用它,什么实例都不会出现。
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def move(self, dx, dy):
self.x += dx
self.y += dyPoint 是类;Point(3, 4) 造出一个对象。类本身也可以看作一种 抽象:使用者通过方法接触点,而不必关心坐标存在哪两个格子里。改内部表示时,只要方法约定不变,外面的代码仍能用。
名字从哪来
class 本义是「类别」。分类学把生物归入纲、目、科;面向对象编程把「同一类事物」写成代码。1960 年代的 Simula 引入了 class 这个词,后来 Smalltalk、C++、Java、Python 都沿用。__init__ 是 initialize 的缩写,在对象刚造出来时做初始化。self 表示「正在说话的这个对象自己」。
「面向对象」并不要求把每一行都写成 class。数字、字符串在 Python 里已经是对象。类是在你需要「一份数据加上能对它做的事」并且这种组合会反复出现时,才值得画出的图纸。
它怎么工作
类里的函数通常叫方法。第一个参数约定写成 self,调用 p.move(1, 0) 时,Python 把 p 传给 self。对象的数据挂在 self 的属性上,互不影响:类定义是共享的,数据默认不共享。定义时要写 self;通过对象调用时不必传入,解释器会代劳。漏写 self,参数个数会对不上。
函数 也可以处理点的坐标,但数据和操作是分开的。类把它们绑在一张图纸上,适合「会长期存在、身上带着状态」的事物。字典 也能装 x 和 y,却没有配套的 move。当操作开始变多,类比一堆字典更不容易散。
生活里在哪里
建筑设计图与一栋栋按图建成的房子:「学生」这个类别都有姓名和年级,但每个人的值不同;同一型号的实验仪器,操作按钮相同,读数各自独立。图纸约束的是这一类该有什么,而不是把所有个体焊成同一个。能给对象随便加一堆互不相关的属性,不等于应该加——类的意义就是约束。
和相近概念的差别
类是图纸,对象是造出来的个体。不要把两者说成同一个词。模块是许多类与函数的仓库;一个类通常不足以代替整个 模块。元组可以表示成套数据,但没有你自己定义的方法名。需要轻量传递一份不该被改的结果时,元组往往够用;需要状态与操作长期绑在一起时,才请出类。
常见误会
误会 1:写了 class,程序就会自动出现对象。
必须调用类来构造,例如 p = Point(0, 0)。
误会 2:所有对象共享同一份 self.x。
每个对象有自己的属性。类定义是共享的,实例数据默认不共享。
误会 3:方法里可以省略 self。
定义时要写;通过对象调用时不必传入。漏写会导致参数个数对不上,或把本该属于对象的状态写到别处去。
想知道更多
- 书:埃里克·马瑟斯《Python编程:从入门到实践(第3版)》
- 书:艾伦·唐尼《像计算机科学家一样思考Python(第2版)》
- 书:布鲁克希尔《计算机科学概论》
未登录时不会保存学习进度