面向对象 Object Oriented
概述
面向过程
1.分析出解决问题的步骤,然后逐步实现。
例如:婚礼筹办
– 发请柬(选照片、措词、制作)
– 宴席(场地、找厨师、准备桌椅餐具、计划菜品、购买食材)
– 婚礼仪式(定婚礼仪式流程、请主持人)
2.公式:程序 = 算法 + 数据结构
3.优点:所有环节、细节自己掌控。
4.缺点:考虑所有细节,工作量大。
面向对象
1.找出解决问题的人,然后分配职责。
例如:婚礼筹办
– 发请柬:找摄影公司(拍照片、制作请柬)
– 宴席:找酒店(告诉对方标准、数量、挑选菜品)
– 婚礼仪式:找婚庆公司(对方提供司仪、制定流程、提供设备、帮助执行)
2.公式:程序 = 对象 + 交互
3.优点
(1)思想层面:
– 更接近于人的思维方式。
– 有利于梳理归纳、分析解决问题。
(2) 技术层面:
– 高复用:对重复的代码进行封装,提高开发效率。
– 高扩展:增加新的功能,不修改以前的代码。
– 高维护:代码可读性好,逻辑清晰,结构规整。
类和对象
语法
定义类
1.代码
class 类名:
“”“文档说明”""
def init(self,参数列表):
self.实例变量 = 参数
方法成员
#实例成员:对象的成员
#作用:表示对象的信息,与对象的行为
class A:
def __init__(self,参数):
self.实例变量 = 参数
def 实例方法名称(self):
print(self.实例变量)
a01 = A(10)
print(a01.实例变量)
a01.实例方法名称
- 说明
– 类名所有单词首字母大写.
– init 也叫构造函数,创建对象时被调用,也可以省略。
– self 变量绑定的是被创建的对象,名称可以
创建对象(实例化)变量 = 构造函数(参数列表)
class Wife: #类,首字母大写
# 1.数据成员 姓名 年龄 性别 ...
def __init__(self, name, age, sex): #形参self必不可少,还必须位于其他参数的前面
# self "自己",调用当前方法的对象
print(id(self)) #忽略,只为了看保存地址
self.name = name #self.name = name获取存储在形参name中的值,并将其存储在变量name中
self.age = age
self.sex = sex
# 2.方法成员 做饭 ...
def cooking(self):
print(id(self)) #忽略,只为了看保存地址
print(self.name + "做饭")
实例成员:
实例变量
1.语法
(1)定义:对象.变量名
(2)调用:对象.变量名
2.说明
(1)首次通过对象赋值为创建,再次赋值为修改.
w01 = Wife( “丫头”)
w01.name = “晓蒂”
(2)通常在构造函数(init)中创建。
w01 = Wife(“晓蒂”,24)
print(w01.name)
(3)每个对象存储一份,通过对象地址访问。
3.作用:描述所有对象的共有数据。
dict:对象的属性,用于存储自身实例变量的字典。
class Wife02:
def __init__(self, name,age):
self.name = name
self.age = age
w01 = Wife02("丫头")
w01.name = "晓蒂"
print(w01.__dict__) #此时实例变量是:{'name': '晓蒂'}
print(w01.name) #晓蒂
w01 = Wife02("丫头")
print(w01.__dict__) #此时实例变量是:{'name': '丫头'}
实例方法
1.语法
(1) 定义: def 方法名称(self, 参数列表):
方法体
(2) 调用: 对象地址.实例方法名(参数列表)
不建议通过类名访问实例方法
2. 说明
(1) 至少有一个形参,第一个参数绑定调用这个方法的对象,一般命名为"self"。
(2) 无论创建多少对象,方法只有一份,并且被所有对象共享。
3. 作用:表示对象行为。
class Wife:
--snip--
# 调用 __init__(self,name,age,sex) 方法
w01 = Wife("丫头", 24, "女")
print(id(w01)) #忽略,只为了看保存地址
# 调用对象的方法 w01 将自身传入方法
w01.cooking() #访问类的属性,使用句点表示法
w02 = Wife("晓蒂", 22, "男")
w02.cooking()
print(id(w02))
输出结果
2077339916224 #地址
2077339916224
2077339916224
丫头做饭
2077340285872
2077340285872
晓蒂做饭
2077340285872
在内存中,方法只有一份.而对象有多份.
练习题1:
学生student是一个类 ,具有姓名,性别,年龄,成绩:
具有学习study,工作work等行为
class Student: #类首字母大写
def __init__(self,name,sex,age,score):
self.name = name
self.sex = sex
self.age = age
self.score = score
def student(self):
print(str(self.name) + " 学习")
# 或者
#print(self.name, " 学习")
def work(self):
print(self.name, "工作")
#s01 悟空对象的地址
s01 = Student("悟空", "男", 28, 99)
s02 = Student("八戒", "男", 29, 88)
#通过对象地址,调用对象方法,会自动传递对象地址
s01.student()
s02.work()
输出结果:
悟空 学习
八戒 工作
练习2:
敌人
class Enemy:
def __init__(self, name = "", hp = 0, atk = 0.0, atk_speed = 0.0): #血量,伤害...设定初始值
self.name = name
self.hp = hp
self.atk = atk
self.atk_speed = atk_speed
def print_self(self):
print(self.name, self.hp, self.atk, self.atk_speed)
在控制台中输出3个敌人,存入列表。将敌人列表输出(调用print_self)到控制台
class Enemy:
def __init__(self, name = "", hp = 0, atk = 0.0, atk_speed = 0.0):
self.name = name
self.hp = hp
self.atk = atk
self.atk_speed = atk_speed
def print_self(self):
print(self.name, self.hp, self.atk, self.atk_speed)
list_enmy= []
for i in range(3):
e = Enemy()
e.name = input("请输入姓名:")
e.hp = int(input("请输入血量:"))
e.atk = float(input("请输入攻击力:"))
e.atk_speed = float(input("请输入攻击速度:"))
list_enmy.append(e)
for item in list_enmy:
item.print_self()
在敌人列表中,根据姓名查找敌人对象
def get_enemy_for_name(list_enemy,name):
#遍历敌人列表
for item in list_enmy:
#如果有指定名称的敌人对象
if item.name == name:
#则返回对象地址
return item
list01 = [
Enemy("zs",100,10,2),
Enemy("ls",200,20,1),
Enemy("ww",300,5,1)
]
re = get_enemy_for_name(list01,"ls")
if re != None:
re.print_self()
else:
print("没有找到")
总结
1.类:一个抽象的概念,即生活中的”类别”。
2.对象:类的具体实例,即归属于某个类别的”个体”。
3.类是创建对象的”模板”。
– 数据成员:名词类型的状态。
– 方法成员:动词类型的行为。
4.类与类行为不同,对象与对象数据不同。
例如:(1)学生student是一个类,具有姓名,年龄等数据;
具有学习study,工作work等行为。
对象:悟空同学,28岁。
八戒同学,29岁。
(2)车 car是一个类,具有类型type,速度speed等数据;
启动start,停止stop,行驶run等行为。
对象:宝马,180.
比亚迪,100.
(3)狗dog是一个类,具有类型,姓名,重量weight等数据,
拉臭臭shit,玩play等行为。
对象:拉布拉多
金毛
(4)字符串str是一个类,”abc”是一个对象。