面向对象介绍
- 面向对象:是一种编程思想(OOP),这种编程思想更加符合人的逻辑思维,使用面向对象可以提高开发速度和代码重用率。面向对象符合大型程序开发,后期维护比过程开发要好。
- 核心关注是对象,是将参与问题的事物对象抽离出来,重点关注对象的行为,通过行为的调用完成整个业务操作,主要实现方式是类和对象。
面向过程
-
核心关注是解决问题的步骤,将解决问题的每个步骤封装成函数,通过函数的逐步调用,得到问题的处理结果,主要实现方式是函数式编程
如:早上吃个早餐再上班 面向过程 早上出发-->买早餐-->吃早餐-->上班 函数 函数 函数 函数 面向过程编程,最直观的实现方式就是函数式编程,这里函数可以重复使用,更多时候只能用在固定流程中,函数复用率较低 面向对象 核心关注是对象,是将参与问题的事物对象抽离出来,重点关注对象的行为 早上吃个早餐再上班 人[对象] 走路, 买早餐,吃早餐,上班 早餐店[对象] 卖早餐 公司[对象] 提供工位 吃饭 面向过程 买菜-->买调料-->洗菜-->炒菜-->吃菜 面向对象 采购:买菜,买调料 厨师:洗菜,炒菜 顾客:吃菜 面向过程:事事亲力亲为 面向对象:别人实现好的拿来直接用
类和对象
-
术语:
- 类:是对一群具有相同特征或者行为的事物的统称(人,电脑,苹果)
- 对象:是由类创造出来的实体,具体到某一个事物就是对象(张伟强,我桌子上的电脑)
- 属性:描述这类事物的特征(人:姓名,身高,年龄)
- 方法:描述这类事物的具体行为(人:吃饭,睡觉,打游戏)
-
类和对象的关系:对象是类的实例,类是对象的模板
-
类的声明
class 类型名称: """类的文档注释""" def __init__(self): #声明属性特征的地方 pass def 方法名称(self): #定义对象的行为 pass 类型名称:标识符命名规范(数字,字母,下划线组成,不能数字开头) 同时符合大驼峰命名法(帕斯卡命名):一个或者多个单词组成,每个单词首字母大写 属性特征:就是一个变量,必须和self一起使用 遵循变量的命名规则:见名知意,下划线命名 方法行为:就是一个函数,遵循函数命名规范 其他规范:类型声明内部第一行包含文档注释,描述类型的作用,在类型内部先声明属性,再声明方法
案例操作
需求:声明一个普通用户类型,类型包含用户名,密码,昵称,有保存和删除的方法 class User: """用户类型""" def __init__(self): """记录用户属性""" self.username = "张伟强" self.password = "123" self.nickname = "强哥" def save(self): """保存方法""" pass def delete(self): """删除方法""" pass
面向对象设计开发
-
面向对象分析(OOA:Object-Oriented Analysis)
- 从用户需求出发,分析项目中需要解决的问题,抽象项目中的功能和互相依赖 的关系,确定功能开发过程中的限制条件
-
面向对象设计(OOD:Object-Oriented Design)
- 根据分析得到的具体的问题,抽取参与解决问题的对象
-
面向对象编程(OOP:Object-Oriented Programming)
-
面向对象测试(OOT:Object-Oriented Testing)
需求:二哈拆家 分析(OOA):二哈,家(房子中的家具) 设计(OOD):二哈-->狗的类型(属性:姓名,年龄 方法:拆东西) 家-->家具类型(属性:沙发,颜色) 编程(OOP):编写代码 测试(OOT):运行代码 软件开发周期 调研需求(售前工程师)-->需求分析(产品经理)-->确定设计方案(架构师/技术总监)-->开发(UI,web,后端)-->测试项目(测试工程师)-->部署(运维工程师)
实例属性和实例方法
-
实例属性:是类型中用于描述每个对象具体数据的,在类型声明过程中,将实例属性声明在
__init__
()方法中,通过接收传递的参数数据进行数据初始化class User: """用户类型""" def __init__(self,username,password,nickname): """记录用户属性""" self.username = username self.password = password self.nickname = nickname
-
实例方法:是类型中描述每个对象行为操作的,通过函数语法进行体现,将对象的行为函数声明在类型的内部,成为类型的实例方法
class User: """用户类型""" def save(self): """保存方法""" pass def delete(self): """删除方法""" pass
-
类属性
-
类属性:属于类型的特征,能被当前类型的所有对象访问
类属性的基本语法 1.位置:声明在类的内部,方法的外部 2.规范:类属性也是属性,也是一个变量,遵循变量的命名规范 发表文章,文章数据无论是普通用户还是管理员用户都快访问 class Databases: """数据类型""" #保存文章类属性 articel_dict = dict()
-
对象的构建
-
通过声明的类型,可以创建该类型对应的具体对象
格式 对象名 = 类名() user = User("张伟强","123","强哥")
-
创建对象时就可以将数据通过参数传递给
__init__
()方法完成对象的初始化,并将创建好的对象地址储存在user变量中,通过user变量可以找到或者引用创建的对象。 -
创建对象会自动执行
__init__
()方法class User: """用户类型""" def __init__(self,username,password,nickname): """记录用户属性""" print("开始执行对象初始化") self.username = username self.password = password self.nickname = nickname def save(self): """保存方法""" pass def delete(self): """删除方法""" print("执行删除操作") # 创建user对象,会自动执行__init__()方法 user = User("张伟强","123","强哥") #对象的实例属性:通过对象直接拿到实例属性 print(user.username) # 对象的实例方法 user.delete()
-
self关键字
- 描述的是当前对象自身,谁调用,self就是谁
- 注意:声明在方法的第一个位置参数上,是一个形参,但是约定俗称使用self
class User: """用户类型""" def __init__(self,username): """记录用户属性""" print("内部self的内存地址:",id(self)) self.username = username # 创建user对象,会自动执行__init__()方法 user = User("张伟强") #user = User(user,"张伟强") #内部已实现这种传递方式 #Python会将对象本身当成第一个参数传递给self # print(user.username)
-
查看对象的内存地址
print("外部创建对象的内存地址:",id(user))
-
对象的创建过程
-
申请空间–>创建对象–>属性初始化
-
类名(),准备创建对象,申请内存空间–>调用
__new__
()方法,创建对象–>调用__init__
()方法,对象初始化–>将创建好的对象赋值给"="左边的变量class User: """用户类型""" def __init__(self,username): """记录用户属性""" print("对象初始化操作") self.username = username def __new__(cls, *args, **kwargs): """创建对象""" print("开始创建对象") return object.__new__(cls) user = User("张伟强") 注意:创建对象会执行__new__()方法,对象创建完会执行__init__()方法
-
练习1:需求每位同学有自己的姓名和年龄,可以自我介绍,如:我叫xxx,今年xx岁,请多多关照!
分析:学生类,属性:姓名,年龄 方法:自我介绍
class Student:
"""学生类"""
def __init__(self,name,age):
"""初始化属性"""
self.name = name #stu1.name="张伟强"
self.age = age
def introduce(self):
"""自我介绍的方法"""
# print(f"我叫{self.name},今年{self.age}岁,请多多关照!")
print(f"我叫{self.name},今年{self.age}岁,分数是{self.score},请多多关照!")
stu1 = Student("张伟强",20)
# stu1.introduce()
#可以使用 对象名.属性名 = 属性值 的方式给对象添加属性
stu1.score = 90
stu1.introduce()
对象的打印
-
直接打印对象,会得到对象存储的内存地址数据
print(user) #<__main__.User object at 0x00000000006D8C88> print(id(user)) #7179400 二者是一样的
-
#可以通过 对象名.属性名 查看属性值,但是当属性比较多时,查看属性就不太方便#打印对象时,会自动调用
__str__
()方法重写__str__()方法,改变对象的返回值 class User: """用户类型""" def __init__(self,username,password,nickname): """记录用户属性""" self.username = username self.password = password self.nickname = nickname def __str__(self): print("--str--") # return "123" return f"{self.username} {self.password} {self.nickname}" user = User("张伟强","123","强哥") #打印对象会自动执行__str__()方法 print(user)
-
当对象包含在组合数据类型中,直接打印组合数据类型,此时对象有变成原来的内存地址形式
print([user]) #[<__main__.User object at 0x0000000002168CF8>]
-
在类型中添加一个
__repr__
()方法,用于对象包含在组合数据类型中时,按照自定义的方式展示对象的数据def __repr__(self): print("--repr--") return f"{self.username} {self.password} {self.nickname}" user = User("张伟强","123","强哥") #打印对象会自动执行__str__()方法,如果没有此方法,会寻找__repr__()方法 print(user) #__str__,张伟强 123 强哥 print([user]) #__repr__,张伟强 123 强哥
-
-
老张开车去东北
需求:发动车辆,输入姓名,车型,到达的目的地(面向过程) 定义车辆发动函数,驾驶函数,到达目的地函数 import time def start(): """驾驶员""" name = input("请输入姓名:") print("用户:",name) #调用车辆驾驶函数 driver(name) def driver(name): """驾驶""" car = input("请输入车的型号") print(f"{name}驾驶{car},准备出发。。。") area = input("请输入要到达的目的地") #调用到达目的地函数 run(area) def run(area): """车行驶到达目的地""" for i in range(10): time.sleep(0.5) print("->",end='') print("经过跋山涉水,到达目的地",area) start() 面向对象 """ 人类 属性:姓名,年龄,性别 方法:开车 (传递一个车对象,直接调用车行驶的方法,不需要关系车是如何行驶的) 车类 属性:品牌,颜色 方法:行驶 地点类 属性:省市县 """ class Person: """人的类型""" def __init__(self,name,age,gender): """属性初始化方法""" self.name = name self.age = age self.gender = gender def driver(self,car): """开车,人的行为""" print(f"{self.name}准备出发") #调用车对行驶的方法 car.run("东北") class Car: def __init__(self,brand,color): """属性初始化方法""" self.brand = brand self.color = color def run(self,area): print(f"{self.color}的{self.brand}发动了,准备去{area}") #创建出所有参数问题的对象 # per1 = Person("老张",50,"男") # qirui = Car("瑞虎5x","灰色") # per1.driver(qirui) aodi = Car("奥迪A6","白色") per2 = Person("老王",45,"男") per2.driver(aodi)