全部博文(408)
分类: Python/Ruby
2006-07-24 17:38:19
class定义类。class
后跟类名和:创建了一个新的类。后面跟着一个缩进的语句块形成类体。self
。
有两种类型的域——类的变量和对象的变量。
类的变量 由一个类的所有对象(实例)共享使用。只有一个类变量的拷贝,所以当某个对象对类的变量做了改动的时候,这个改动会反映到所有其他的实例上。
对象的变量 由类的每个对象/实例拥有。因此每个对象有自己对这个域的一份拷贝,即它们不是共享的,在同一个类的不同实例中,虽然对象的变量有相同的名称,但是是互不相关的。
例子:#!/usr/bin/python
class
Person
:
'''Represents a person.'''
population =
0
def
__init__
(self, name):
'''Initializes the person's data.'''
self.name = name
print
'(Initializing %s)'
% self.name
# When this person is created, he/she
# adds to the population Person.population +=
1
def
__del__
(self):
'''I am dying.'''
print
'%s says bye.'
% self.name
Person.population -=
1
if
Person.population ==
0
:
print
'I am the last one.'
else
:
print
'There are still %d people left.'
% Person.population
def
sayHi
(self):
'''Greeting by the person.
Really, that's all it does.''' print
'Hi, my name is %s.'
% self.name
def
howMany
(self):
'''Prints the current population.'''
if
Person.population ==
1
:
print
'I am the only person here.'
else
:
print
'We have %d persons here.'
% Person.population
swaroop = Person(
'Swaroop'
)
swaroop.sayHi()
swaroop.howMany()
kalam = Person('Abdul Kalam'
)
kalam.sayHi()
kalam.howMany()
swaroop.sayHi()
swaroop.howMany()
输出:
(Initializing Swaroop)
Hi, my name is Swaroop.
I am the only person here.
(Initializing Abdul Kalam)
Hi, my name is Abdul Kalam.
We have 2 persons here.
Hi, my name is Swaroop.
We have 2 persons here.
Abdul Kalam says bye.
There are still 1 people left.
Swaroop says bye.
I am the last one.
说明:
这个例子有助于说明类与对象的变量的本质。这里,population
属于Person
类,因此是一个类的变量。name
变量属于对象(它使用self
赋值)因此是对象的变量。
观察可以发现__init__
方法用一个名字来初始化Person
实例。同样可以发现,self.name
的值根据每个对象指定,这表明了它作为对象的变量的本质。
只能使用self
变量来参考同一个对象的变量和方法。这被称为 属性参考 。
在这个程序中还看到docstring对于类和方法同样有用。
在Python的类中有很多方法的名字有特殊的重要意义。如:__init__
方法在类的一个对象被建立时,马上运行。这个方法可以用来对对象做一些初始化。还有一个特殊的方法__del__
,它在对象消逝的时候被调用。但是很难保证__del__方法在何时运行。如果要指明它的运行,需要使用del
语句。
面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过 继承 机制。继承完全可以理解成类之间的 类型和子类型 关系。
一个子类型在任何需要父类型的场合可以被替换成父类型,即对象可以被视作是父类的实例,这种现象被称为多态现象。
#!/usr/bin/python
# Filename: inherit.pyclass
SchoolMember
:
'''Represents any school member.'''
def
__init__
(self, name, age):
self.name = name
self.age = age print
'(Initialized SchoolMember: %s)'
% self.name
def
tell
(self):
'''Tell my details.'''
print
'Name:"%s" Age:"%s"'
% (self.name, self.age),
class
Teacher
(SchoolMember):
'''Represents a teacher.'''
def
__init__
(self, name, age, salary):
SchoolMember.__init__(self, name, age)
self.salary = salary print
'(Initialized Teacher: %s)'
% self.name
def
tell
(self):
SchoolMember.tell(self) print
'Salary: "%d"'
% self.salary
class
Student
(SchoolMember):
'''Represents a student.'''
def
__init__
(self, name, age, marks):
SchoolMember.__init__(self, name, age)
self.marks = marks print
'(Initialized Student: %s)'
% self.name
def
tell
(self):
SchoolMember.tell(self) print
'Marks: "%d"'
% self.marks
t = Teacher('Mrs. Shrividya'
,
40
,
30000
)
s = Student('Swaroop'
,
22
,
75
)
print
# prints a blank line
members = [t, s]
for
member
in
members:
member.tell() # works for both Teachers and Students
输出
(Initialized SchoolMember: Mrs. Shrividya)
(Initialized Teacher: Mrs. Shrividya)
(Initialized SchoolMember: Swaroop)
(Initialized Student: Swaroop)
Name:"Mrs. Shrividya" Age:"40" Salary: "30000"
Name:"Swaroop" Age:"22" Marks: "75"
说明:
为了使用继承,把基本类的名称作为一个元组跟在定义类时的类名称之后。然后,基本类的__init__
方法使用self
变量调用,这样可以初始化对象的基本类部分。Python不会自动调用基本类的constructor。
在方法调用之前加上类名称前缀,然后把self
变量及其他参数传递给它。
Python总是首先查找对应类型的方法。如果它不能在导出类中找到对应的方法,它才开始到基本类中逐个查找。基本类是在类定义的时候,在元组之中指明的。
如果在继承元组中列了一个以上的类,那么它就被称作 多重继承 。