面向对象与类
# 面向过程与面向对象介绍
# 面向过程
- 核心是"过程"二字,过程相当于"流水线"
- 核心思想是将程序流程化,是分步骤解决问题的思想
# 面向对象
- 核心是"对象"二字
- 对象相当于一个"容器",用来盛放数据与功能的
- 模块也可以称之为一个对象
- 核心思想是将程序"整合",程序=数据+功能
- 将数据与功能整合在一起
# 面向对象优缺点
# 优点
- 整合 —> 解耦合 —> 高扩展性
- 提高程序的解耦合程度,进而增强程序的可扩展性
# 缺点
- 设计复杂,且容易过度设计,没必要用到面向对象却也用
# 类
# 类的介绍
- 用于存放多个对象的共有部分,面向对象需要先定义类,然后再调用类实现对象的实例化
- 类是对象中相似数据与功能的集合体,所以类中最常见的是变量与函数的定义
- 但类体代码实际可以包含任意代码的,类体的代码在定义阶段就会运行,而调用不会
- 解决了对象的代码冗余问题
# 定义
- 类的定义
- 建议使用大驼峰命名法
class Category:
pass
1
2
2
- 类中变量的定义
class Category:
var = 123456
1
2
2
- 类中功能的定义
class Category:
def func():
pass
1
2
3
2
3
# 类的名称空间
- 类体的名称空间是局部的,是在定义阶段产生的
# 访问类中的名称
类名.类中的名称
- 例如
Category.var
- 同等于:
Category.__dict__['var']
# 创建对象
# 调用类产生对象
类名()
- 会产生一个对象并返回其内存地址
对象名 = 类名()
- 调用类的过程又称之为实例化
- 创建一个对象并将其内存地址与对象名绑定
- 实例化过程
- 先产生一个空对象
- python会自动调用类中的
__init__
方法,将空对象与其他参数传入__init__
- 返回初始化完的对象
- 例如
obj = Category()
# 在对象中创建新名称(不建议)
- 如果在类中并没有定义该名称
- 而内部函数又要调用在外部创建的名称时
- 就需要添加myself形参,并使用
"myself.名称"
来调用创建的名称
- 例如
class Category:
def pr(myself):
print(myself.name)
obj = Category()
obj.name = 'me'
obj.pr()
1
2
3
4
5
6
2
3
4
5
6
# __init__初始化
# __init__
- 会在调用类时,自动触发执行,用来为对象初始化自己独有的数据
__init__
内应该存放的是为对象初始化属性的代码,但也可以存放其他任意代码__init__
方法必须返回None,返回对象是类做的事情
# 需要在类定义__init__()
__init__
会在对象实例化时,自动进行执行,实现初始化
class xxx:
def __init__(空对象, 其他形参...):
pass
1
2
3
2
3
# 传入参数到__init__()
obj = xxx(实参...)
- 对象实例化时,会将传入的参数,传递给
__init__
- 且python会将空对象自动传入
- 相当于
xxx(空对象,其他实参)
- 只不过由于空对象会自动传入,所以需要省略
- 空对象一般约定俗成命名为
self
- 相当于
# 类的属性
# .后面的就是类的属性
# 类的数据属性
- 类的数据属性是共享给所有对象用的,不同的对象访问的内存地址是一样的
# 类的函数属性
- 类的函数属性是绑定给对象用的,虽然所有对象指向的都是相同的功能
- 但是绑定到不同的对象,就是不同的绑定方法,内存地址各不相同
# 类与对象的数据查找顺序
# 查找顺序
- 先查找对象的,如果没有,再查找类的
# 类中已经定义的数据,是无法通过对象修改的
- 如果从对象进行修改,由于在对象中没有找到该名称,所以会在对象名称空间中创建一个新变量
print(obj.xxx) # 对象中没有,从类找
obj.xxx = 10 # 对象没有,在对象中创建
print(obj.xxx) # 对象有,直接用对象中的
1
2
3
2
3
- 除非是通过名称间接操作类的数据,如列表的append、pop等,而非直接=号赋值
- 例如
class.xxx = []
obj.xxx.append('test')
1
2
2
# 类函数的绑定方法
# 绑定方法介绍
- 绑定方法的特殊之处在于谁来调用绑定方法,就会将谁(对象)当做第一个参数,自动传入
# 类中的函数需要定义一个用于传入对象的形参
- 约定俗成一般写
self
# 例子
stud1_obj.test()
- 这里调用就会自动把stud1_obj作为test()方法的参数传入给函数的第一个形参,不需要自己传入