面向对象
面向对象回顾(上节课)
- 面向对象的结构
- id(标识)
- type(类型)
- value(值)
- 面向对象的介绍
- python是一门面向对象的编程语言
- 好处 —— 复用性比较高且方便维护
- 坏处 —— 编写有一定难度
- 类
- python提供一些内置类 —— 如list() int() float() set()…
- 自己创建的类
- 是一个可以创建对象的对象
- 类型是type类
- 创建的对象可以称为类的实例 —— p = Person() p是Person类创建出来的对象,或叫p是类的实例,或叫p是实例化对象、Person是类对象
- 可以向类对象中添加变量和函数。在类对象中添加的变量叫属性,在类对象中添加的函数叫方法。类中的属性和方法都是公共的,该类所有的实例化对象都可以访问
- 在实例化对象中,可以添加属性(方法:对象.属性名 = 属性值)
- 在类中添加的方法,会默认传递一个参数self(这个参数写字母都不为错,但建议写self)
- 实例对象为什么可以访问类中的属性和方法
- 当调用一个对象的属性时,解释器会在当前对象中寻找是否含有该属性或方法
- 如果有,则直接返回当前对象的属性或方法
- 如果没有,则在类对象中寻找
- 如果有,则返回类对象的属性或方法
- 如果没有,则报错
self参数讲解
- 类对象和实例对象都可以保存属性(方法)
- 如果属性(方法)是所有实例所共享的,则应该保存到类对象中
- 如果属性(方法)是某个实例所独有的,则应该保存到实例对象中
- 通常情况下,属性保存到实例对象中
- 通常情况下,方法保存到类对象中
- 方法每次调用时解释器会自动传递一个实参
- 哪个对象调用,方法的第一个实参就是哪个对象
- 通常会将这个对象命名为self
# 方法的第一个形参通常定义为self的原因
class Person:
def run(x):
print(x)
p1 = Person()
p2 = Person()
p1.run() # <__main__.Person object at 0x00000203DDCCEFD0>
print(p1) # <__main__.Person object at 0x00000203DDCCEFD0>
p2.run() # <__main__.Person object at 0x00000203DDCE7880>
print(p2) # <__main__.Person object at 0x00000203DDCE7880>
# 通过上面的演示,p1和p1.run()为同一个对象,p2和p2.run()为同一个对象,那么run方法中的x形参就是某个实例对象在调用run方法时将实例对象自己当做实参传入。因此用self表示更为贴切
class Person:
def run(self): # 方法的第一个实参是实例对象,哪个实例对象调用就是那个实例对象
print('%s跑的好快呀!'% self.name)
p1 = Person()
p2 = Person()
p1.name = '超人'
p2.name = '灭霸'
p1.run() # 超人跑的好快呀!
p2.run() # 灭霸跑的好快呀!
特殊方法
在类中可以定义一些特殊方法(魔术方法)
- 特殊方法的表示 —— 两个单下划线开头和两个单下划线结尾(__方法__)
- 特殊方法调用 —— 每创建一个实例对象,特殊方法自动调用一次,不需要自己调用
__init__方法
- 作用 —— 初始化实例化对象属性的方法
- 语法:
def __init__(self,…): # 通过self向新创建的对象中初始化属性
代码块
# 查看init方法如何调用(创建实例对象时自动调用)
class Person:
def __init__(self):
print('执行init语句')
p1 = Person() # 执行init语句
p2 = Person() # 执行init语句
# 通过init方法的self进行实例化属性的创建(初始化实例对象属性)
class Person:
def __init__(self,name):
self.name = name
p1 = Person() # TypeError: __init__() missing 1 required positional argument: 'name'
p2 = Person('超人')
print(p2.name) # 超人
类的基本结构
class 类名([父类]):
公共属性...
def __init__(self,...): # 对象的初始化方法
...
# 对象的其他方法
def ...(self):
...
def ...(self):
...