Python学习笔记 - 面向对象编程
根据廖雪峰的Python教程做成的笔记,其中不包含全部知识点,仅是重点或是容易发生混淆或者忘记的部分
1. 类基础
1.1 类定义
class student(object):
def __init__(self, name, score):
self.name = name
self.score = score
def printScore():
print('%s: %s' % (self.name, self.score))
student1 = student('Tom', 99)
student1.printScore()
# 结果:Tom: 99
()
括号内是要集成的类名,基类的话在括号内填object
。- init()函数是类的初始化函数。
- 与C++不同的是,类内的成员变量在
__init__()
函数中直接初始化即可,不必显示的定义出来。
1.2 访问限制
类的成员变量默认是共有的,如果要作为私有成员变量,在变量名前加__
即可。
class student(object):
def __init__(self, name, score):
self.__name = name #变量名前加"__"就是私有成员变量
self.__score = score
def printScore():
print('%s: %s' % (self.__name, self.__score))
2. 继承和多态
2.1 基础
class Animal(object):
def run(self):
print('Animal is running!')
class Dog(Animal): # 支持继承多个父类,用","逗号隔开
def run(self): # 子类重写父类方法
print('Dog is running!')
# 测试
animal = Dog()
animal.run()
# 结果:Dog is running!
2.2 与C++的区别
2.2.1 构造函数
项目 | C++ | Python | 备注 |
---|---|---|---|
构造函数 | 创建子类对象时自动调用父类初始化函数。 | 需要在子类__init__() 函数中手动显示调用父类__init__() 函数。 | - |
构造函数调用顺序 | 父类 => 子类成员 => 子类自身 | 子类自身 => 父类 => 子类对象 |
class Animal(object):
def __init__(self):
print('Animal init start!')
print('Animal init end!')
class Dog(Animal):
def __init__(self):
print('Dog init start!')
Animal.__init__(self)
print('Dog init end!')
# 测试
foo = Dog()
# 结果:
# Dog init start!
# Animal init start!
# Animal init end!
# Dog init end!
2.3 多继承
Python允许子类同时继承多个父类,继承时使用逗号分隔。
class A(object):
def __init__(self):
print('class A init start')
print('class A init End')
class B(A):
def __init__(self):
print('class B init start')
A.__init__(self) # 调用父类A的初始化函数
print('class B init End')
class C(A): # C继承A
def __init__(self):
print('class C init start')
A.__init__(self) # 调用父类A的初始化函数
print('class C init end')
class D(C, B):
def __init__(self):
print('class D init start')
B.__init__(self) # 调用父类B的初始化函数
C.__init__(self) # 调用父类C的初始化函数
print('class D init end')
2.4 super()机制
上面的例子有一些缺点,比如说如果修改了父类名称,那么在子类中会涉及多处修改,并且创建类对象时父类A的初始化函数会执行2次,非常累赘。由此引入super()机制。
上面例子使用super()机制实现如下:
class A(object):
def __init__(self):
print('class A init start')
print('class A init End')
class B(A):
def __init__(self):
print('class B init start')
super(B, self).__init__()
print('class B init End')
class C(A):
def __init__(self):
print('class C init start')
super(C, self).__init__()
print('class C init end')
class D(C, B):
def __init__(self):
print('class D init start')
super(D, self).__init__()
print('class D init end')
# 测试
foo = D()
# 初始化函数调用顺序:
# class D init start
# class C init start
# class B init start
# class A init start
# class A init End
# class B init End
# class C init end
# class D init end
同理,调用父类同名函数也可以通过super()机制实现:
class Animal(object):
def run(self):
print('Animal is running')
class Dog(Animal):
def run(self):
print('Dog is running')
# 测试
dog = Dog()
dog.run()
super(Dog, dog).run()
# 结果:
dog is running
Animal is running
3. 实例属性和类属性
3.1 实例属性
实例属性即类的成员变量,在类的__init__()
函数里定义即可。
class Student(object):
def __init__(self, name, age):
self.name = name
self.age = age
self.grade = ''
self.number = 0
3.2 类属性
类似于C++中的static成员变量,所有类对象共有一份。
例:统计学生总数
class Student(object):
total = 0 # 定义类属性,注意是在__init__()函数外
def __init__(self, name, age):
self.name = name
self.age = age
self.grade = ''
self.number = 0
Student.total = Student.total + 1
# 测试
std1 = Student('Tom', 17)
std2 = Student('Jone', 18)
std3 = Student('Jerry', 17)
print('There are %d students in class.' % Student.total)
注意:类属性和实例属性的命名最好不要相同,使用时容易发生混淆!