1 面向对象
类和对象都是面向对象中的重要概念。面向对象是一种编程思想, 即按照真实世界的思维方式构建软件系统。
例如,在真实世界的校园里有学生和老师,学生有学号、姓名、所 在班级等属性(数据),还有学习、提问、吃饭和走路等动作(方法) 。如果我们要开发一个校园管理系统,那么在构建软件系统时,也会有 学生和老师等“类”,张同学、李同学是学生类的个体,被称为“对象”, “对象”也被称为“实例”。
2 定义类
Python中的数据类型都是类,我们可以自定义类,即创建一种新的 数据类型。Python中类的定义语法格式如右图所示。 定义小汽车(Car)类的代码如下:
小汽车(Car)类继承了object类,object类是所有类的根类,在Pyth on中任何一个类(除object外)都直接或间接地继承了object,直接继承 object时(object)部分的代码可以省略。
3 创建对象
类相当于一个模板,依据这样的模板来创建对象,就是类的实例化 ,所以对象也被称为“实例”。
4 类的成员
4.1 实例变量
实例变量就是对象个体特有的“数据”,例如狗狗的名称和年龄等。
通过Python指令运行文件,输出结果。
4.2 构造方法:
类中的__init__()方法是一个非常特殊的方法,用来创建和初始 化实例变量,这种方法就是“构造方法”。在定义__init__()方法时, 它的第1个参数应该是self,之后的参数用来初始化实例变量。调用构造 方法时不需要传入self参数。
构造方法的示例代码如下:
4.3 实例方法
实例方法与实例变量一样,都是某个实例(或对象)个体特有的方 法。
定义实例方法时,它的第1个参数也应该是self,这会将当前实例与 该方法绑定起来,这也说明该方法属于实例。在调用方法时不需要传入 self,类似于构造方法。
下面看一个定义实例方法的示例:
4.4 类变量
类变量是属于类的变量,不属于单个对象。
例如,有一个Account(银行账户)类,它有三个成员变量:amoun t(账户金额)、interest_rate (利率)和owner(账户名)。amount和ow ner对于每一个账户都是不同的,而interest_rate对于所有账户都是相同 的。amount和owners是实例变量,interest_rate是所有账户实例共享的变 量,它属于类,被称为“类变量”。 类变量的示例代码如下:
4.5 类方法
类方法与类变量类似,属于类,不属于个体实例。在定义类方法时 ,它的第1个参数不是self,而是类本身。
5 封装性
封装性是面向对象重要的基本特性之一。封装隐藏了对象的内部细 节,只保留有限的对外接口,外部调用者不用关心对象的内部细节,使 得操作对象变得简单。
例如,一台计算机内部极其复杂,有主板、CPU、硬盘和内存等, 而一般人不需要了解它的内部细节。计算机制造商用机箱把计算机封装 起来,对外提供了一些接口,如鼠标、键盘和显示器等,使用计算机就 变得非常简单。
5.1 私有变量
为了防止外部调用者随意存取类的内部数据(成员变量),内部数 据(成员变量)会被封装为“私有变量”。外部调用者只能通过方法调用 私有变量。
在默认情况下,Python中的变量是公有的,可以在类的外部访问它 们。如果想让它们成为私有变量,则在变量前加上双下画线(__)即可 。 示例代码如下:
由于在类的外部不可以访问私有变量,因此上述代码在运行时会发 生错误,通过Python指令运行文件,输出结果。
5.2 私有方法
私有方法与私有变量的封装是类似的,在方法前加上双下画线(__ )就是私有方法了。示例代码如下:
由于在类的外部不可以访问私有方法,因此上述代码在运行时会发 生错误,通过Python指令运行文件,输出结果。
5.3 使用属性
为了实现对象的封装,在一个类中不应该有公有的成员变量,这些 成员变量应该被设计为私有的,然后通过公有的set (赋值)和get(取 值)方法访问。 使用set和get方法进行封装,示例代码如下:
使用属性方式修改上面的示例,代码如下:
6 继承性
继承性也是面向对象重要的基本特性之一。
在现实世界中继承关系无处不在。例如猫与动物之间的关系:猫是 一种特殊动物,具有动物的全部特征和行为,即数据和操作。在面向对 象中动物是一般类,被称为“父类”;猫是特殊类,被称为“子类”。特殊 类拥有一般类的全部数据和操作,可称之为子类继承父类。
6.1 Python中的继承
在Python中声明子类继承父类,语法很简单,定义类时在类的后面 使用一对小括号指定它的父类就可以了。 下面是动物类继承图。
通过Python指令运行文件,输出结果:
6.2 多继承
在Python中,当子类继承多个父类时,如果在多个父类中有相同的 成员方法或成员变量,则子类优先继承左边父类中的成员方法或成员变 量,从左到右继承级别从高到低。 示例代码如下:
6.3 方法重写
如果子类的方法名与父类的方法名相同,则在这种情况下,子类的 方法会重写(Override)父类的同名方法。
7 多态性
多态性也是面向对象重要的基本特性之一。“多态”指对象可以表现 出多种形态。 例如,猫、狗、鸭子都属于动物,它们有“叫”和“动”等行为,但是 叫的方式不同,动的方式也不同。
7.1 继承与多态
在多个子类继承父类,并重写父类方法后,这些子类所创建的对象 之间就是多态的。这些对象采用不同的方式实现父类方法。 示例代码如下:
7.2 鸭子类型测试与多态
Python的多态性更加灵活,支持鸭子类型测试。鸭子类型测试指: 若看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么 这只鸟可以被称为鸭子。
由于支持鸭子类型测试,所以Python解释器不检查发生多态的对象 是否继承了同一个父类,只要它们有相同的行为(方法),它们之间就 是多态的。 例如,我们设计一个函数start(),它接收具有“叫”speak()方法 的对象,代码如下:
8 练一练
1 在下列选项中,哪些是类的成员。()
A.成员变量
B.成员方法
C.属性
D.实例变量
2 判断对错:(请在括号内打√或×,√表示正确,×表示错误)。
1)在Python中,类具有面向对象的基本特性,即封装性、继承性 和多态性。()
2)__init__()方法用来创建和初始化实例变量,这种方法就是“ 构造方法”。()
3)类方法不需要与实例绑定,需要与类绑定,在定义时它的第1个 参数不是self。()
4)实例方法是在类中定义的,它的第1个参数也应该是self,这个 过程是将当前实例与该方法绑定起来。()
5)公有成员变量就是在变量前加上两个下画线(__)。()
6)属性是为了替代get()方法和set()方法。()
7)子类继承父类时继承父类中的所有成员变量和方法。()
8)Python中的继承是单继承。()
3 请介绍什么是“鸭子类型”?