类的基本认识和使用
一 面向对象和面向过程
问题1:咱们之前写的代码属于面向对象吗?
答:不属于,属于面向过程
问题2:什么面向过程,什么是面向对象,二者之间有什么区别?
答:这是两种不同的开发代码的模式.
-
面向过程开发(Procedure Oriented Programming,POP):按照业务的逻辑顺序,通过函数来实现某一功能,从上到下逐一调用函数的过程,比较适合功能变化不多的场景,C语言编写操作系统。
-
面向对象设计(Object Oriented Programming,OOP):将数据与对数据的操作看做一个整体即对象,以对象为中心的编程思想,以对象的⻆度去处理问题,通过对象之间的操作完成任务。这种编程理念更符合我们人的逻辑思维。使用面向对象编程可以提高我们的开发速度和代码的重用率,适合于变化多,场景复杂情况。
通俗理解:
面向过程----老板自己独自作战----所有的事情都需要自己去玩,亲力亲为
面向对象—老板雇佣员工—老板分配职责,发号施令
面向过程开发(Procedure Oriented Programming,POP):按照项目的逻辑顺序,从上到下依次执行,通过函数来实现某一功能,按照功能顺序,逐一调用函数的过程。
#开发五子棋游戏
1 展示棋盘
2 黑棋落子
3 刷新
4 判断胜负
5 白棋落子
6 刷新
7 判断胜负
8 重复2-7
特点
1 符合初学者思维习惯,能够理解python代码
2 不利于团队开发,开发效率较低
换一种思路:将一个整体拆分为不同部分,研究每一个部分能够做那些事?
- 棋盘
- 展示棋子
- 刷新界面
- 棋子
- 落子
- 判定系统
- 判定胜负
面向对象开发(oop)
1 棋盘---展示棋子
2 棋子---落子
3 棋盘---刷新
4 判定系统---进行判定
特点:
1 解决了不同功能之间的强耦合性,有利于团队开发。
2 对于大型项目,直接分析逻辑有时候会有困难,采用面向对象方式有利于降低开发难度。
二 类和对象
面向过程和面向对象之间区别(已解决)
类和对象及其关系(已解决)
属性和方法分别是什么(已解决)
疑问:用什么来实现我们学习的面向对象思想?
答:类和对象
1类和对象
类:许多具体事物具有相同的特性或是行为的一个统称,是一个抽象概括。
成语:物以类聚,人以群分
对象:具体的某些特征或是行为某一个事物,具体的。
2 如何区分类和对象
原则:分析事物是具体指代还是抽象概括。
3 类和对象之间关系
类就是具体对象的抽象,对象是类的具体实现。
类就是模板,对象是具体的事物。
2 属性和方法
疑问:如何去描述事物的特征和行为?属性和方法
1 属性:就是描述事务具有的特征,静态的,名称性的描述。
2 方法:就是描述事物具有哪些行为,动态的,动词性的描述。
描述手机
特征:黑色的,210g重,华为品牌。
行为:能接打电话,上网冲浪,提醒我起床…
描述棋子
特征:椭球形,白色/黑色,5g
行为:能够遮挡棋盘
3 类和对象的声明和规范
-
类的声明格式
class 类型名: def __init__(self,[参数]): """描述特征""" # (属性) self.属性名 = 属性值 pass def 方法名(self,[参数]): """描述行为""" pass
-
类的声明规范
- 类名
- 属于标识符的一种,遵循标识符规则。(强制)
- 使用大驼峰命名法:每个单词首字母大写,UserName(推荐)
- 属性名: 参考变量名命名规则和规范。例如:self.height = 170
- 方法名: 参考函数命名规则和规范。def eat(): print(“我在吃饭‘)
- 类名
-
示例:
分析:用户类应该具有的属性和方法
- 属性:用户名,密码
- 方法:加入购物车
class User: def __init__(self,name,pwd): """描述用户的特征""" self.user_name = name # 定义用户名 self.user_password = pwd # 定义密码 def select_course(self): """加入购物车""" print("已加入购物车")
-
对象的创建
创建格式: 对象名 = 类名([参数]) #参数根据类内__init__是否有参数而定 # 创建了张三对象 zs = User('zs','123456')
-
对象使用属性和方法
使用对象的属性:对象名.属性名
使用对象的方法:对象名.方法名()
zs.user_name # 查看对象的用户名属性 zs.select_course() # 查看张三具有的方法
4 项目开发过程
(1)岗位
- 项目经理
- 产品经理
- 设计师
- 开发工程师----你
- 测试工程师
- 运维工程师
(2)开发流程和设计过程
(3) 面向对象的设计开发
-
面向对象分析(OOA)
分析用户的原始需求,从需求中分析出需要的类,类的属性和方法
-
面向对象设计(OOD)
设计用哪些对象和类来实现分析的结果
-
面向对象编程(OOP)
如何使用代码具体实现以上需求
-
面向对象测试(OOT)
测试代码或是功能是否满足需求
案例演示
博客系统(CSDN)----完成博文的编写过程
OOA:博文类
-
属性:编写日期,编写人
-
方法:写博文,发布博文
OOD: Article
- 属性:date,author
- 方法:write_article,public_article
OOP:
class Article:
def __init__(self,date,author):
"""博客系统属性的声明"""
self.date = date
self.author = author
def write_article(self):
print("我在认真的写博文")
print(f"博文写于{self.date}")
print(f"作者是{self.author}")
def public_article(self):
print("博文完成,现在需要发布")
art = Article()
OOT:测试功能
三 实例属性和方法
案例:英雄联盟中的英雄
- 属性:名字,血量,普攻伤害,技能
- 方法:释放技能,跑
class Hero:
def __init__(self,name,hp,damage,skill):
"""定义英雄特征"""
self.name = name # 实例属性
self.hp = hp
self.damage = damage
self.skill = skill
def unleash(self):
print(f"{self.name}开始释放技能{self.skill}")
def run(self):
print(f"在run方法内部self是{self}")
print(f"{self.name}开始逃跑")
gai = Hero('盖伦',650,60,"旋转") # 创建对象
huang = Hero("皇子",600,,66,'插旗子')
# 盖伦、皇子调用自己血量属性
print(gai.hp) # 650
print(huang.hp) # 600
# 盖伦和皇子调用跑方法
gai.run() # 盖伦在跑
huang.run() # 皇子在跑
1 概念
实例:对象的别称
实例属性:对象的属性,具体的,每个对象特征的值是不同的。定义在__init__中
实例方法:对象的方法,每个对象都有相同的方法名,但是具有不同的操作方法。只要一个方法包含一个参数self那么我们就可以把它称作实例方法。
2 self作用
问题:同一个方法打印出的内容不一致?由于有self参数,这个参数不需要我们手动传递具体的值,在我们调用方法时候解释器会自动将对象本身作为self的参数传递进入。
self 指代对象本身,谁调用我,我就是谁
class Hero:
def __init__(self, name, hp, damage, skill):
"""定义英雄特征"""
self.name = name # 实例属性
self.hp = hp
self.damage = damage
self.skill = skill
def unleash(self):
print(f"{self.name}开始释放技能{self.skill}")
def run(self):
print(f"在run方法内部self是{self}")
print(f"{self.name}开始逃跑")
# 创建对象
gai = Hero('盖伦', 650, 60, "旋转")
huang = Hero('皇子',600,66,'插旗子')
print(f"在类外盖伦对象地址是{gai}")
gai.run() # 打印盖伦的内存地址
print()
print('========================')
print(f"在类外皇子对象地址是{huang}") #
huang.run() # 打印皇子的内存地址
备注:self 就是一个形参,其实可以更换为任意一个合法名字,但是一般默认就是使用self。
四 对象的构建
1 对象创建语法
对象名 = 类名([参数])
创建英雄对象
gai = Hero('盖伦', 650, 60, "旋转")
huang = Hero('皇子',600,66,'插旗子')
2 对象调用属性和方法
# 调用属性
对象名.属性名
gai.name # 调用盖伦的姓名属性
# 调用方法
对象名.方法名([参数])
gai.run() # 盖伦调用跑的方法
3 创建对象过程
3.1 魔法方法:Python内部有一种特殊的方法,双下换线开头且双下划綫结尾的方法,特殊之处在于这样的方法不需要显式的调用,会自动执行,每个特殊方法都有自己特殊的触发时机。
_init_(self,…):实例初始化方法,触发时机是:对象创建完成后,实例出初始化的时候回自动调用该方法。
# 创建英雄对象
gai = Hero('盖伦', 650, 60, "旋转") # 创建对象,对象初始化
class Person:
def __init__(self):
print("init方法")
zs = Person()
3.2 创建对象过程
_new_(cls):创建对象。触发时机:创建对象的时候回自动调用此方法
了解:Person由object对象创建出来的
class Person:
def __new__(cls):
print("new方法") # 没有创建一个对象
return object.__new__(cls)
def __init__(self):
print("init方法")
zs = Person()
备注:创建对象及实例化过程中会调用两个魔法方法,_new_(cls),__init(self),先执行new方法,后执行init方法
五 打印对象
1 直接打印对象
class Hero:
def __init__(self, name, hp, damage, skill):
"""定义英雄特征"""
self.name = name # 实例属性
self.hp = hp
self.damage = damage
self.skill = skill
def unleash(self):
print(f"{self.name}开始释放技能{self.skill}")
def run(self):
print(f"在run方法内部self是{self}")
print(f"{self.name}开始逃跑")
# 创建对象
gai = Hero('盖伦', 650, 60, "旋转")
huang = Hero('皇子',600,66,'插旗子')
# 打印对象
print(gai) # 打印对象的内存地址
2 使用__str__方法:在打印对象本身会自动调用该方法。
注意:自定义__str__方法时需要返回一个字符串
class Hero:
def __init__(self, name, hp, damage, skill):
"""定义英雄特征"""
self.name = name # 实例属性
self.hp = hp
self.damage = damage
self.skill = skill
def __str__(self):
return "这是hero对象"
def run(self):
print(f"在run方法内部self是{self}")
print(f"{self.name}开始逃跑")
# 创建对象
gai = Hero('盖伦', 650, 60, "旋转")
huang = Hero('皇子',600,66,'插旗子')
# 打印对象
print(gai) # 打印自定义返回的内容
# 创建一个英雄列表
hero_list = [gai,huang]
print(hero_list) # 列表中打印仍旧是对象的内存地址
3 _repr_(self):在打印对象本身会自动调用该方法。包含该对象时候也会调用该方法
class Hero:
def __init__(self, name, hp, damage, skill):
"""定义英雄特征"""
self.name = name # 实例属性
self.hp = hp
self.damage = damage
self.skill = skill
def __str__(self):
return "这是hero对象"
def __repr__(self):
return f"在repr中的{self.name}"
def run(self):
print(f"在run方法内部self是{self}")
print(f"{self.name}开始逃跑")
# 创建对象
gai = Hero('盖伦', 650, 60, "旋转")
huang = Hero('皇子',600,66,'插旗子')
# 打印对象
print(gai) # str 方法返回字符串
# 创建一个英雄列表
hero_list = [gai,huang]
print(hero_list) # [在repr中的盖伦, 在repr中的皇子]
self.hp = hp
self.damage = damage
self.skill = skill
def __str__(self):
return "这是hero对象"
def __repr__(self):
return f"在repr中的{self.name}"
def run(self):
print(f"在run方法内部self是{self}")
print(f"{self.name}开始逃跑")
创建对象
gai = Hero(‘盖伦’, 650, 60, “旋转”)
huang = Hero(‘皇子’,600,66,‘插旗子’)
打印对象
print(gai) # str 方法返回字符串
创建一个英雄列表
hero_list = [gai,huang]
print(hero_list) # [在repr中的盖伦, 在repr中的皇子]
注意:如果类中既包含str方法又包含repr方法,在打印对象时有限执行str方法,如果没有str方法才会调用repr