Python支持面向对象的三大特征:封装,继承,多态,子类继承父类同样可继承到父类的变量和方法。
1.定义类
Python定义类的语法如下:
class 类名:
执行语句…
零到多个类变量…
零到多个方法…
类名只要是合法标识符即可,每个单词首字母大写,其余字母小写,单词与单词之间不使用任何标识符。
类成员之间定义顺序没有任何影响。
类变量属于类本身,用于定义该类本身所包含的状态数据。
实例对象属于该类的对象,用于定义对象所包含的状态数据。
方法则用于定义该类的对象的行为或功能实现。
Python是一门动态的语言,它的类所包含的类变量可以动态增加或者删除。程序在类体中为新变量赋值就是增加类变量,程序也可在任何地方为已有的类增加变量;使用del语句删除已有类的类变量。
Python对象的实例变量可以动态增加或者删除。对新实例变量赋值就是增加实例变量,程序也可在任何地方为已有的对象增加实例变量;使用del语句删除已有对象的实例变量。
在类中定义的方法默认是实例方法,实例方法的第一个参数会被绑定到方法的调用者(该类的实例)-----因此实例方法至少应该定义一个参数,该参数通常被命名为self。
____init____这个方法被称为构造方法,构造方法用于构造该类的对象,Python通过调用构造方法返回该类的对象。
构造方法是一个类创造对象的根本途径,如果开发者没有为该类定义任何构造方法,那么Python会自动为该类定义一个只包含一个self参数的默认的构造方法。
2.对象的产生和使用
创造对象的根本途径是构造方法,调用某个类的构造方法即可创建这个类的对象。例如:
对象访问变量和方法的语句是: 对象.变量|方法(参数)。在这种方式中,对象是主调者,用于访问该对象的变量或方法。例如:
self.name = name与self.age = age两行代码用传入的name,age参数(这两个参数都有默认值)对self的name,age变量赋值,也就是对该构造方法初始化的对象§的name,age赋值,即为p对象增加了name,age两个实例变量。
3.对象动态性
由于Python是一门动态语言,因此程序完全可以为p对象动态增加实例变量----只要为它的新变量赋值即可,也可以动态的删除实例变量----使用del语句即可删除。例如:
为p对象动态增加的方法,Python不会自动将调用者自动绑定到第一个参数(即使第一个参数是self也没用)。例如:
上面代码分别使用函数,lambda表达式为p对象动态增加方法。
如果希望动态增加的方法也能自动绑定到第一个参数,则可以借助于types模块下的MethodType进行包装。例如:
4.实例方法和自动绑定self
对于在类体中定义的实例方法,Python会自动绑定方法的第一个参数,第一个参数总是指向调用该方法的对象。根据第一个参数出现位置的不同,第一个参数所绑定的对象略有区别。
- 在构造方法中引用该构造方法正在初始化的对象
- 在普通实例方法中引用调用该方法的对象
由于实例方法(包括构造方法)的第一个self参数会自动绑定,因此程序在调用普通实例方法,构造方法时不需要为第一个参数传值。
self参数最大的作用就是引用当前方法的调用者。通过self为该对象增加实例变量,也可以在一个实例方法中访问该类的另一个实例方法或变量。例如:
当Python对象的一个方法调用另一个方法时,不可以省略self。
在构造方法中,self参数代表该构造方法正在初始化的对象。例如:
在Age的构造方法中,self参数总是引用该构造方法正在初始化的对象。
当self参数作为对象的默认引用时,程序可以像访问普通变量那样来访问这个self参数,甚至可以把self参数当成实例方法的返回值。例如:
如果在某个方法中把self参数作为返回值,则可以多次连续调用方法。使用self参数作为方法的返回值可以使程序更加简洁,但可能造成实际意义的模糊。