第六章 面向对象程序设计
1. 类的定义与使用
在面向对象程序设计中,把数据以及对数据的操作封装在一起,组成一个整体(对象),不同对象之间通过消息机制来通信或者同步。对于相同类型的对象进行分类、抽象后,得出共同的特征而形成了类。创建类时用变量形式表示对象特征的成员称为数据成员,用函数形式表示对象行为的成员称为成员方法,数据成员和成员方法统称为类的成员。
Python使用关键字class
来定义类,之后是一个空格,接下俩是类的名字,如果派生自其他基类则需要把所有基类放到一对圆括号中并使用逗号分隔,然后是一个冒号,最后换行并定义类的内部实现。其中类名最好与所描述的事务相关,且首字母一般要大写。
class Car(object):
def showInfo(self):
print('this is a car')
定义了类之后就可以用类来实例化对象,并通过“对象名.成员”的方式来访问其中的数据成员或成员方法。
>>> car = Car()
>>> car.showInfo()
this is a car
2. 数据成员与成员方法
1. 私有成员与成员方法
从形式上看,在定义类的成员时,如果成员名以两个下划线开头但是不以两个下划线结束则表示是私有成员。私有成员在类的外部不能直接访问,一般是在类的内部进行访问和操作,或者在类的外部通过调用成员的公有成员方法来访问,而公有成员是可以公开使用的,既可以在类的内部进行访问,也可以在外部程序中访问。
注意,Python并没有对私有成员提供严格的访问保护机制,通过一种特殊方式对象名._类名__xxx
也可以在外部程序中访问私有成员,但不建议这么做。
>>> class Test:
def __init__(self, value = 0): #构造方法,创建对象时自动调用
self.__value = value #私有数据成员
def setvalue(self, value): #公有成员方法,需要显式调用
self.__value = value #在类内部可以直接访问私有成员
def show(self): #成员方法,公有成员
print(self.__value)
>>> t = Test()
>>> t.show() #在类外部可以直接访问非私有成员
0
>>> t._Test__value #在外部使用特殊形式访问私有数据成员
0
.
代表成员访问运算符。
在Python中,以下划线开头或结束的成员名有特殊的含义:
_xxx
:以一个下划线开头,保护成员,一般建议在类对象和子类对象访问这些成员,不建议通过对象直接访问;在模块中使用一个或多个下划线开头的成员不能用from module import *
导入,除非在模块中使用__all__
变量明确指明这样的成员可以被导入。__xxx
:以两个下划线开头但不以两个下划线结束,表示私有成员,一般只有类对象自己能访问,子类对象也不能访问该成员,但在对象外部可以通过对象名.__类名__xxx
这样的特殊形式访问。__xxx__
:前后各两个下划线,系统定义的特殊成员。
2. 数据成员
- 属于对象的数据成员主要在构造方法
__init__()
中定义,而且在定义和在实例方法中访问数据成员时往往以self作为前缀,同一个类的不同对象的数据成员之间不影响。其中,定义时前加__
的是属于对象的私有变量,不加的是属于对象的公开变量。 - 属于类的数据成员的定义不在任何成员方法之内,是该类所有对象共享的,不属于任何一个对象。
在主程序中或类的外部,属于对象的数据成员只能通过对象名访问;而属于类的数据成员可以通过类名或对象名访问。
利用类数据成员的共享性,可以实时获得该类的对象数量,而且可以控制该类可以创建的对象最大数量。
>>> class Demo():
num = W0
def __init__(self):
if Demo.num>0:
raise Exception('only one')
demo.num += 1
>>> d1 = Demo()
>>> d2 = Demo()
Traceback (most recent call last):
File "<pyshell#22>", line 1, in <module>
d2 = Demo()
File "<pyshell#20>", line 5, in __init__
raise Exception('only one')
Exception: only one
3. 成员方法
公有方法和私有方法一般是指属于对象的实例方法,其中私有方法的名字以两个下划线开始;公有方法通过对象名直接调用,私有方法不能通过对象名直接调用,只能在其他实例方法中通过前缀self进行调用或在外部通过特殊的形式来调用。
所有实例方法