面向对象
目录
面向对象的概念
对比 面向过程的优缺点和使用场景
类和对象的概念
如何创建类和对象
如何设计属性
属性的查找顺序
初始化方法
绑定方法与非绑定方法
什么是面向对象编程
面向对象编程——Object Oriented Programming,简称OOP 。
面向对象是一种编程思想,是前辈们总结出的经验 指导程序员如何编写出更好的程序,核心就是对象。
将数据和处理数据的程序封装到对象中,以提高软件的重要性、灵活性和拓展性为首要目的
为什么需要面向对象
通常情况下,应用程序对扩展性和维护性的要求都是非常高的,
因为现在的软件都是不断的添加新的功能,也就是说一款应用程序诞生后,
都需要不断的更新维护
优点
1、扩展性 对象之间相互独立,当一个对象发生修改后,其他对象没有任何影响
2、灵活性 提高了程序的灵活性
3、重用性
缺点
1、程序的复杂度提高了
2、无法准确预知结果
面向对象的使用场景
需要经常变化的软件,对扩展性要求较高的程序 通常是直接面向对象 列如qq 微信
面向过程编程思想
关注的核心是过程 过程就是一步一步的执行步骤 就是先干啥在干啥
优点 逻辑清晰 复杂问题简单化 流程化
缺点 扩展性差 可维护性差 重用性差
面向过程的使用场景
一旦完成,基本很少改变的场景,对扩展性要求较低的程序 列如系统内核,git 以及Apache HTTP Server
把大象装进冰箱案列
面向过程步骤
1、打开冰箱
2、装入冰箱
3、关闭冰箱
面向对象:
找个具备装大象的技能的对象
在面向对象中程序员的角度发生改变 从具体的操作者变成了指挥者
强调 对象不是凭空产生的 需要我们自己设计的
类和对象
类和对象是面向对象(oop)中的最核心的两个概率
什么是类
类既类型 类别 ,是一种抽象概念,是一系列具备相同特征和相同行为的对象集合
为什么要有类
现实生活中,通过对对象的分析总结 等到类型 用类型来标识不同对象之间的差异;
在程序中,同样用于标识不同对象之间的差异
面向对象(oop)第一步要做的就是定义需要的类
对象
就是具体存在的某种事物 具备自己的特征
对象就是特征和技能的集合体
类和对象的关系
类包含一系列对象
对象属于某个类
站在不同角度,定义对象和类的关系
在生活中是现有对象再有类
在程序中是先有类 才能有对象 我们必须告诉计算机这类类的对象有什么特征 有什么行为
总结
在使用面向对象编程时 第一步就是思考需要什么样的对象 对象具备什么样的特征和行为 从而根据这些信息总结出需要的类型
创建类和对象
定义类的语法
#class 类的名称:
#类中的内容 描述属性和行为
#描述属性用变量
#描述行为用函数
#类名称的书写规范 见名知意
#名称是大驼峰命名
# 大驼峰 就是第一个字母大写
class Student:
pass
创建对象的语法
class Student:
pass
p = Person()
#调用类 既类名加括号
#类里放的是共有的
#对象里放的是自己独有的
类和对象的查找顺序
如果类中和对象中存在的同样的属性 先访问对象 如果没有在访问类
属性的增删改查
属性可以写在类中
类中的属性是所有对象公共的
也可以写在对象中,对象中的属性是每个对象的
增加属性
对象变量名称.属性 = 属性值
删除属性
del 对象的变量名称.属性名称
修改
对象.属性 = 新的值
查看属性
对象.__dict__ 访问的是对象的属性
__doc__ 对像的注释
————class__ 访问对象的类信息
初始化对象属性 init
什么是初始化方法
用于为对象的属性设置初始值的函数
为什么要初始化
在类的实例中,一些属性是必须存在的,就可以使用初始化函数来完成,比如Student对象中的name属性 它是必须的,用于唯一标识一个学生
class Student:
def__init__(self,name):
self.name = name
特点
特点 当实例化对象时 会自动执行__init__方法
热点2 会自动将对象作为第一个参数传入 参数名称位self self可以是别的名字 但是不建议改
功能 用户给对象赋值初始值
对象的精髓所在就是将数据和处理数据的函数整合到一起 这样拿到一个对象 就同时拿到了需要处理的数据以及处理数据的函数
对象初始化列子
class Student:
school = "old_boy"
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
def study (self):
print(self)
def say_hi (self):
print('hello i am a good boy! my name is %s my age is %d'%(self.name,self.age)) #多个赋值要用括号括起来
stu1 = Student('隔壁老王',18,'man')
stu2 = Student('狗子',18,'man')
stu1.say_hi()
stu2.say_hi()
对象的绑定方法
默认情况下 类中的方法都是对象绑定方法
当使用对象调用时 会自动传入对象本身,作为第一个参数
当使用类名来调用时 他就是一个普通函数,有几个函数就得传几个函数
类绑定方法
类绑定方法 用@classmerhod来装饰
特殊之处
不管用类还是对象调用 都会自动传入类本身 作为第一个参数
什么时候绑定对象 当函数逻辑需要访问对象中的数据时
什么时候绑定给类 当函数逻辑需要访问类中的数据时
非绑定方法
既不需要访问类的数据 也不要访问对象的数据
语法:@staticmethod
英雄大乱斗
import random
import time
class Hero:
def __init__(self,name,blood,level,att,q,w,e):
self.name = name
self.blood = blood
self.level = level
self.att = att
self.q = q
self.w = w
self.e = e
def attack(self,enemy):
enemy.blood-=self.att
print("%s对%s释放了普通攻击 造成了%s的伤害 剩余血量%s"%(self.name,enemy.name,self.att,enemy.blood))
if enemy.blood <= 0:
print("%s被%s使用普通攻击技能缴获了" % (enemy.name, self.name))
def q(self,enemy):
enemy.blood-=self.att
print("%s对%s释放了q造成了%s的伤害 剩余血量%s"%(self.name,enemy.name,self.q,enemy.blood))
if enemy.blood <= 0:
print("%s被%s使用q亲技能击杀了" % (enemy.name, self.name))
def w(self,enemy):
enemy.blood-=self.att
print("%s对%s释放了w 造成了%s的伤害 剩余血量%s"%(self.name,enemy.name,self.w,enemy.blood))
if enemy.blood <= 0:
print("%s被%s使用w技能击杀了" % (enemy.name, self.name))
def e(self,enemy):
enemy.blood-=self.att
print("%s对%s释放了e 造成了%s的伤害 剩余血量%s"%(self.name,enemy.name,self.e,enemy.blood))
if enemy.blood <= 0:
print("%s被%s使用E技能击杀了" % (enemy.name, self.name))
h1 = Hero("火男",1000,10,100,300,2334,232)
h2 = Hero("瞎子",2000,10,58,234,233,232)
h3 = Hero("老亚索",2000,10,58,234,233,232)
h4 = Hero("老木乃",2000,10,58,234,233,232)
def random_hero(heros):
hero_index = random.randint(1, len(heros))
return heros[hero_index]
while True:
# # 把所有的攻击方法装到字典里 为了随机取出一个
funcs = {1: Hero.q, 2: Hero.w, 3: Hero.e, 4: Hero.attack}
func_index = random.randint(1, 4)
func = funcs[func_index]
# 把所有的英雄方法装到字典里 为了随机取出一个
heros = {1: h1, 2: h2}
hero = random_hero(heros)
# 剩余的英雄们
other_heros = {}
new_index = 1
for k, v in heros.items():
if v != hero:
other_heros[new_index] = v
new_index += 1
# 从剩余的英雄中随机挑出一个英雄来挨打
enemy = random_hero(other_heros)
# 打他
func(hero, enemy)
if enemy.blood <= 0:
break
time.sleep(0.5)