面向对象编程基础
类和对象
- 简单的说,类是对象的蓝图和模板,而对象是类的实例。
- 这个解释虽然有点像用概念在解释概念,但是从这句话我们至少可以看出,类是抽象的概念,而对象是具体的东西。
- 在面向对象编程的世界中,一切皆为对象,对象都有属性和行为,每个对象都是独一无二的,而且对象一定属于某个类(型)。
- 当我们把一大堆拥有共同特征的对象的**静态特征(属性)和动态特征(行为)**都抽取出来后,就可以定义出一个叫做“类”的东西。
定义类
在Python中可以使用class
关键字定义类,然后在类中通过之前学习过的函数来定义方法
class Student(object):
# __init__是一个特殊方法用于在创建对象时进行初始化操作
# 通过这个方法我们可以为学生对象绑定name和age两个属性
def __init__(self, name, age):
self.name = name
self.age = age
def study(self, course_name):
print('%s正在学习%s.' % (self.name, course_name))
# PEP 8要求标识符的名字用全小写多个单词用下划线连接
# 但是很多程序员和公司更倾向于使用驼峰命名法(驼峰标识)
写在类中的函数,我们通常称之为(对象的)方法,这些方法就是对象可以接收的消息。
创建和使用对象
def main():
# 创建学生对象并指定姓名和年龄
stu1 = Student('骆昊', 38)
# 给对象发study消息
stu1.study('Python程序设计')
stu2 = Student('王大锤', 15)
stu2.study('思想品德')
if __name__ == '__main__':
main()
访问可见性
- 在很多面向对象编程语言中,我们通常会将对象的属性设置为私有的(private)或受保护的(protected),简单的说就是不允许外界访问
- 而对象的方法通常都是公开的(public),因为公开的方法就是对象能够接受的消息。
- Python中,属性和方法的访问权限只有两种,也就是公开的和私有的,如果希望属性是私有的,在给属性命名时可以用两个下划线作为开头
class Test:
def __init__(self, foo):
self.__foo = foo
def __bar(self):
print(self.__foo)
print('__bar')
def main():
test = Test('hello')
# AttributeError: 'Test' object has no attribute '__bar'
test.__bar()
# AttributeError: 'Test' object has no attribute '__foo'
print(test.__foo)
if __name__ == "__main__":
main()
- 在实际开发中,我们并不建议将属性设置为私有的,因为这会导致子类无法访问(后面会讲到)。
- 所以大多数Python程序员会遵循一种命名惯例就是让属性名以单下划线开头来表示属性是受保护的,本类之外的代码在访问这样的属性时应该要保持慎重。
- 这种做法并不是语法上的规则,单下划线开头的属性和方法外界仍然是可以访问的,所以更多的时候它是一种暗示或隐喻
面向对象的支柱
面向对象有三大支柱:封装、继承和多态。
- 封装:隐藏一切可以隐藏的实现细节,只向外界暴露(提供)简单的编程接口
- 我们在类中定义的方法其实就是把数据和对数据的操作封装起来了,在我们创建了对象之后,只需要给对象发送一个消息(调用方法)就可以执行方法中的代码
- 也就是说我们只需要知道方法的名字和传入的参数(方法的外部视图),而不需要知道方法内部的实现细节(方法的内部视图)。