1. 认识面向对象编程
正所谓物以类聚,面向对象程序设计(Object-Oriented Programming, OOP)是一种基于“对象(objects)”概念的编程范式,它可以包含数据/data和代码/code,对数据而言:字段(fields)形式的数据通常称为特性(attributes)或属性(properties);对代码而言:过程(procedures)形式的代码,通常称为方法(methods)。
面向对象的程序设计与面向过程的函数式编程范式不同,面向过程的编程以业务为驱动,聚焦功能模块的分解,自顶向下、逐步求精;而面向对象编程聚焦“对象”的状态和交互,对象之间既有相互联系,又可以相互作用。

2. 类与对象
在面向对象的编程范式中,类(class)是一个抽象概念,是一系列具有相同特征和行为的事物的统称,对象(object)作为内存区域,可包含任意数量和类型的数据并由标识符引用。类是模板,对象是根据模板创建的特定实例。

面向对象编程具有三大特性:
封装(encapsulation):把数据以及与这个数据相关的操作放在一起,某种意义上来说:封装=数据+代码;类=变量+方法。封装使得对象以外的事物不能随意操作对象内部的属性,以更加抽象的方式对外展现操作接口,隐藏了实现的复杂性,提高了代码复用性,也增强了可维护性。
继承(inheritance):从已经有的类中(基类、父类)派生出新的类(派生类、子类),派生类/子类自动拥有其父类的所有属性和方法。当然,子类还可以定义自己新的属性和方法,且还可以再“遗传”给下一代,下一代将拥有其父类、以及父类的父类的所有属性和方法。面向对象编程的继承机制有效实现了代码的复用,极大地提高了软件开发的效率。
多态(polymorphism):在父类中定义的特征和行为,遗传给子类后,在子类中能表现出和父类不同的行为特征。多态可以为不同数据类型的实体/对象提供统一的接口(interface),这样就可以用一个函数名调用不同对象的函数/方法。从纵向上来看,依赖于继承,派生自同一个父类的不同子类可以通过改写继承到的方法而表现出与父类不同的特性从而表现出多态;从横向上看,依赖于接口(interface),相同父类的不同子类对象虽然使用了相同的函数名称,但却有不同的函数功能,也就是说向不同的对象发送同一条消息,不同的对象在接收时会产生不同的行为,一个接口多种实现从而表现出多态性。

3. 类的创建与实例化
Python创建一个类要用到关键字class,语法格式如下:
class ClassName( ):
# Constructor
def __init__(self, parameter) -> None:
pass
statements
创建对象时使用形如:“对象名 = 类名( )”的格式,会自动调用类的构造函数__init__( )去初始化实例对象。
object = ClassName(arguments)
4. 成员的访问控制
Python虽然没有严格的私有成员概念,但单下划线“_”和双下划线“__”命名的约定,对成员属性和成员方法的“可见”性有其专门含义:
前置单下划线,_var:命名约定,供内部使用/受保护,对python解释器没作用。
后置单下划线,var_:命名约定,规避与Python关键字名字的冲突。
前置双下划线,__var:类的私有成员,类中使用触发名称改写(name mangling),对python解释器有作用。
前后双下划线,__var__:Python定义的特殊方法,自定义的属性中要避免使用。
仅单下划线,_:临时的、无关紧要的。
类的设计中,既要保护变量的私有访问,又希望对象能便捷读取,怎样才能平衡好二者的关系了?一种通行的做法是在类的设计中定义变量为私有,然后再为该变量编写两个成员函数分别用于读和写。

Python为我们提供了属性装饰器@property,将方法变成属性调用。用“@property”装饰的方法为读取操作,其实就是实现了getter功能,用“@属性名.setter”装饰的方法为写入/赋值操作,其实就是实现了setter功能,定义方法的时候“@property”必须在“@属性名.setter”之前,且二者修饰的方法名相同,如果只实现了“@property”而没有实现“@属性名.setter”,那么该属性就成为了只读属性。
5. 类方法
类方法要使用装饰器@classmethod修饰,实例对象的方法第一个参数为self,而类方法第一个参数必须是当前的类自身,一般命名为cls。可以通过类名调用类方法,也可以通过对象名调用类方法,在类的方法中可以调用类本身的其他方法,也可以访问类成员。
逻辑上来说,实例对象的方法是给实例对象用的,类的方法是给类使用的。

6.静态方法
类的静态方法主要用于类对外部函数的封装,有助于整合代码,集成通用性的外部函数到类中。静态方法使用装饰器@staticmethod修饰,它不需要传入默认参数,既没有实例对象方法中的self,也没有类方法中的cls。因此,它既不能访问实例对象的属性和方法,也无法访问类的属性和方法。

一般,我们把类的静态方法当工具使用,静态方法就像是类包含的一个工具包,只是名义上归属类管理,但是不能使用类成员和实例对象成员。