在面向对象的编程中,我们编写表示现实世界的事物和情景的类,并基于这些类来创建对象。编写类的时候我们的定义的一大堆对象都具有通用的行为,我们可以根据需求给每个对象赋予独特的特性
类的特征:
1.可以像函数一样调用类对象。调用将返回另一个对象,也被称为改类的实例
2.类中包含任意名称的属性,开发者绑定和引用这些属性
3.类的属性可以是描述符、函数甚至是普通的数据对象
4.绑定到函数的类属性也被称为改类的方法
5.方法可以有一个特殊的使用py定义的名称,这个名称由名字+前后两个下划线组成,py可以隐式调用这些方法
6.可以从其他类处继承类
8.1 使用和创建类
8.1.1 创建Dog类
例1
方法__init__()
1、类中的函数称为方法,适用于函数的一切都是用于方法,函数和方法目前唯一的区别就是调用的方法不同罢了
2、开头和结尾处的_,这是一种约定,是为了避免py的默认方法和普通方法发生命名冲突
3、在上述示例中__init__()的定义中包含有三个形参:self、name、age
在这个定义中,形参self是必不可少的,且必须位于其他的形参的前面
当我们需要创建根据Dog类创建实例的时候,只需要给后面的两个参数提供相应的值即可
包含形参self的原因:
1、通过__init__()这种方法来创建实例的时候,将自动传入实参self
2、每个与类相关联的方法调用都是自动传递实参self
3、self是一个指向实例本身的引用,使得实例能够访问类中的属性和方法
8.1.2 根据类创建实例
例2
我们通常将首字母大写的名称称作类,将小写的名称看做由类创建的实例
1.访问属性
要访问实例的属性,需要使用句点表示法
2.调用方法
指定实例的名称和要调用的方法,并且用句点分隔他们
3.我们按照需求根据类创建任意数量的实例
8.2 使用类和实例
将类写好以后,我们会将大部分的时间花在根据类创建的实例上面。
我们需要做的有:1、修改实例的属性
2、编写方法以特定的方法来进行修改
8.2.1 给属性指定默认值
类中的每个属性都必须要有初始值,哪怕这个值是0或者是空的字符串
注意:
1、有些时候,在方法__init__()内指定初始值是可行的
2、如果你对某个属性做了上述的处理,就无须包含为它提供初值的形参
例3
8.2.2 修改属性的值(一定要注意细节上的修订是否正确)
1、直接修改属性的值
要修改属性的值,最简单的方法就是通过实例访问它(通过句点表示法来处理)
修改对于本次在程序运行的过程中是永久的,即你直接修改了类本身的定义。
2、通过方法修改属性的值
即存在方法可以帮助我们更新实例中的属性,即在类中存在相应的修改函数
3、通过方法对属性的值进行递增
类似于方法2
例4
8.2.4 限制性访问
在变量名或者函数名前面加上双下划线即可,这样就保证了变量或者函数只能在类内部的函数进行调用
8.3 继承
编写类的时候,不一定总要从0做起。如果说我们需要编写的类是一个现成的类的特殊的版本,我们可以使用继承
一个类继承另一个类的时候,它将自动获得另一个类的属性和方法,原来的类称为父类,新的类称为子类
子类继承了父类的所有的属性和方法,同时还可以自己定义属性和方法
8.3.1 子类的方法__init__()
1、创建子类的时候,父类必须包含在当前文件夹,且位于子类的前面
2、定义子类的时候,必须在括号里面指定父类的名称
3、super()是一个特殊的函数,帮助py将父类和子类关联起来
例5
8.3.2 给子类添加属性和方法
就和在父类中添加属性和方法一样的处理就行
8.3.3 重写父类的方法
就根据py在重新定义的原理进行解释。
对于父类的方法,只要其不符合子类模拟实物的行为,我们就可以对父类的方法进行重新的定义
8.3.4 将实例用作属性
当我们使用代码模拟实物的时候,当我们的类的细节越来越多的时候:属性和方法清单以及文件都越来越长
面对这种情况,我们可能需要将类的一部分作为一个单独的类提取出来
8.4 导入类
8.4.1 导入单个类
导入类是一种有效的编程。
我们可以将一个类转移到一个模块当中,使得整个程序变得更加的干净整洁且易于阅读
通过导入类的方法,我们可以帮助我们将注意力转移到主程序的高级逻辑当中
8.4.2 在一个模块中存储多个类
我们可以根据我们的需求在一个模块中存储任意数量的类
8.4.3 从一个模块中导入多个类
我们可以根据程序文件的需要从一个模块中导入多个类
当我们需要从一个模块中导入多个类的时候
举例:from 文件名 import 类名1,类名2
8.4.4 导入整个模块
当我们导入整个模块以后,我们需要通过句点访问的方式来进行访问我们需要的类
由于我们创建的实例的代码都包含实例名,因此不会与当前文件使用的任何名称发生冲突
8.4.5 导入模块中所有的类
不推荐使用
语法规则:from 模块名 import *
不推荐使用的原因:
1.这种导入方式没有明确的指出你的模块到底使用了那些类
2.这种导入方式还会引发名称问题方面的错误,即可能出现重定义的现象
8.4.6 在一个模块中导入另一个模块
即我们在有的时候需要将类分散到多个模块中,以避免模块太大的问题出现;或者我们需要在同一个模块中存储不想关 的类。将类存储在多个模块的时候,可能会出现一个模块中的类需要依赖另一个模块中的类,当我们遇到这种情况的时 候,我们可以从前一个模块中导入必要的类