初识面向对象 OOP
什么是面向对象?
- 面向对象是一种编程思想,是前辈们总结出的经验,指导程序员如何编写出更好的程序
- 核心是对象,程序就是一系列对象的集合, 程序员负责调度控制这些对象来交互着完成任务
- 在面向对象中程序员的角度发生改变,从具体的操作者变成了指挥者
优点:解决了程序的扩展性,使程序变得更为灵活,增加了程序的重用性
使程序的维护和扩展变得更简单,大大提高程序开发效率
缺点:程序的复杂程度增加;可控性变差,无法像面向过程的程序设计流水线式的可以很精准预测结果
应用场景:对扩展性要求较高的程序,一般集中在用户层,互联网企业等;如我们使用的QQ、微信
##########################
面向过程编程:
- 面向过程的程序设计的核心是过程(流水线式思维)
- 过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西
优点:解决问题的逻辑清晰,极大降低了写程序的复杂度
缺点:扩展性差,代码牵一发而动全身
应用场景:对扩展性要求较低的程序,如 Linux 内核, git 以及 Apache HTTP Server 等
#############################
类
既类型,类别 ,是一种抽象概念;是一系列具备相同特征和相同行为的对象的集合
对象
就是具体存在的某个事物,具备自己的特征和行为;对象就是特征和技能的结合体
PS:类包含一系列对象 对象属于某个类 在程序中是先有类才能有对象
# 创建类和对象 # class 类的名称: # 类中的内容 描述属性和技能 # 描述属性用变量 # 描述行为用函数 # 类名称书写规范:首先是见名知意,名称是大驼峰命名法 # 驼峰就是单词首字母大写 , 大驼峰是第一个字母大写,小驼峰是第一个字母小写 # 如: class Person: #定义一个人类 role = 'person' # 人的角色属性都是人 def walk(self): # 人都可以走路,也就是有一个走路方法,也叫动态属性 print("person is walking...") p = Penson() # 创建对象
# 属性可以写在类中,类中的属性,是所有对象公共的 # 也可以写在对象中,对象中的属性,是每个对象独特的(不一样的) # 如果类中和对象中存在同样的属性,先访问对象 如果没有在访问类 # 属性的增删改查 ``` 增加属性 对象变量名称.属性名称 = 属性值 删除属性 del 对象的变量名称.属性名称 修改 对象.属性 = 新的值 查看属性 访问的是对象的所有属性 print(对象.__dict__) 访问对象的类信息 print(对象.__class__) ```
类的实例化:
# 类名加括号就是实例化,会自动触发__init__函数的运行,可以用它来为每个实例定制自己的特征(初始值) class Person: #定义一个人类 role = 'person' #人的角色属性都是人 def __init__(self,name): self.name = name # 每一个角色都有自己的昵称;
return None # 该函数不能有任何返回值/.... 只能是None 也可以不写
def walk(self): #人都可以走路,也就是有一个走路方法 print("person is walking...") # 实例化的过程就是类——>对象的过程 # 语法:对象名 = 类名(参数) egg = Person('egon') # 类名()就等于在执行Person.__init__() # 执行完__init__()就会返回一个对象。这个对象类似一个字典,存着属于这个人本身的一些属性和方法。
注:self:在实例化时自动将对象/实例本身传给__init__的第一个参数
查看属性和调用方法
print(egg.name) #查看属性直接 对象名.属性名 print(egg.walk()) #调用方法,对象名.方法名()
类属性的补充:类名.__dict__:查出的是一个字典,key为属性名,value为属性值
对象的绑定方法:
默认情况下类中的方法都是对象绑定方法
当使用对象调用该函数时会自动传入对象本身,作为第一个参数
当使用类名来调用时他就是一个普通函数,有几个参数就得传几个参数
class Student: def __init__(self,name): # 默认为绑定对象 self.name = name def say_hi(self): print("hello my name is %s" % self.name)
类的绑定方法:
类绑定方法用@classmethod来装饰
特殊之处:不管用类还是对象调用,都会自动传入类本身,作为第一个参数
class Student: def __init__(self,name): # 默认为绑定对象 self.name = name @classmethod def say_hi(self): # 此时为类的绑定方法 print("hello my name is %s" % self.name)
什么时候绑定给对象:当函数逻辑需要访问对象中的数据时
什么时候绑定给类:当函数逻辑需要访问类中的数据时
非绑定方法:(不常用)
或叫做静态方法,就是即不需访问类的数据,也不需要访问对象的数据
语法:@staticmethod
class Student: def __init__(self,name): # 默认为绑定对象 self.name = name @staticmethod def say_hi(self): # 此时为非绑定方法 print("hello my name is %s" % self.name)
##########################################
英雄大乱斗( 摘自于https://www.cnblogs.com/hellozizi/p/11239516.html )
import random import time # 人物类 class Heros: def __init__(self, name, level, blood, atk, q_atk, w_atk, e_atc): self.name = name self.level = level self.blood = blood self.atk = atk self.q_atk = q_atk self.w_atk = w_atk self.e_atc = e_atc # 普通攻击 def normo_att(self, enemy): enemy.blood -= self.atk print(f'{self.name}对{enemy.name}进行了,普通攻击,造成了{self.atk}点伤害.{enemy.name}剩余血量{enemy.blood}') # Q攻击 def Q(self, enemy): enemy.blood -= self.q_atk print(f'{self.name}对{enemy.name}进行了,Q攻击,造成了{self.atk}点伤害.{enemy.name}剩余血量{enemy.blood}') # W攻击 def W(self, enemy): enemy.blood -= self.w_atk print(f'{self.name}对{enemy.name}进行了,W攻击,造成了{self.atk}点伤害.{enemy.name}剩余血量{enemy.blood}') # E攻击 def E(self, enemy): enemy.blood -= self.e_atc print(f'{self.name}对{enemy.name}进行了,E攻击,造成了{self.atk}点伤害.{enemy.name}剩余血量{enemy.blood}') # 创建人物 h1 = Heros('鼬', 30, 3000, 300, 500, 600, 700) h2 = Heros('大蛇丸', 20, 4000, 200, 400, 500, 600) h3 = Heros('斑', 40, 6000, 600, 700, 800, 900) h4 = Heros('带土', 20, 5000, 300, 500, 600, 700) h5 = Heros('蝎', 20, 3500, 100, 200, 300, 400) # 人物字典 HEROS_DIC = { 1: h1, 2: h2, 3: h3, 4: h4, 5: h5, } # 攻击方式字典 atk_func = { 1: Heros.normo_att, 2: Heros.Q, 3: Heros.W, 4: Heros.E, } # 循环操作 while True: # 从人物字典中随机获取1个索引值,做为发动攻击人物的索引 hero_index = random.randint(1, len(HEROS_DIC)) # 随机获取发动攻击的人物 hero = HEROS_DIC[hero_index] # 将被攻击人物,放进一个新字典,除自己外 enemy_dic = {} new_key = 1 for k, v in HEROS_DIC.items(): if k != hero_index: enemy_dic[new_key] = v new_key += 1 # 从被攻击人物字典中随机获取1个索引值,做为被攻击人物的索引 enemy_index = random.randint(1, len(enemy_dic)) # 获取被攻击人物 enemy = enemy_dic[enemy_index] # 从攻击方式列表中,随机获取1个攻击方式的索引 atk_index = random.randint(1, len(atk_func)) # 将发动攻击的人物和被攻击人物放入攻击方式中 atk_func[atk_index](hero, enemy) # 当被攻击方的血量小于等于0时,即判定被击杀 if enemy.blood <= 0: print(f'{hero.name}击杀了{enemy.name}') break # 为了让过程更有趣一点,所以加入了0.5秒延迟:) time.sleep(0.5)