面向对象:1.面向对象
1.1面向对象概念,
1 """""" 2 """ 3 面向对象概念 4 """ 5 """ 6 1.什么是面向对象? 7 面向对象是一种编程思想, 8 是前辈们总结出的经验, 9 指导程序员如何编写更好的程序,10 11 核心:对象12 程序就是一系列对象的集合,13 程序也调度控制这些对象来交互着完成任务14 """15 16 """"""17 """18 面向过程概念19 """20 """21 1.什么是面向过程编程?22 就类似于设计一条流水线,一环套一环,23 降低复杂度,最后得到清晰明了的结果.24 25 核心:过程26 过程就是一步一步的执行步骤,27 即,先干啥在干啥.28 29 """
1.2面向对象与面向过程
1 """""" 2 """ 3 面向对像 4 """ 5 6 """ 7 面向对像oop 8 1.什么是面向对象? 9 面向对象是一种编程思想,10 是前辈们总结的一套经验,11 指导我们的编程思想,让我们写出更好的程序12 13 核心是对象,14 程序就是一系列对象的集合,15 程序员负责调整控制这些对象来交互着完成任务目标16 2.面向对象的优缺点17 面向对象的三大优点18 1.扩张性19 2.灵活性20 3.重用性(使用次数高)21 缺点:22 1.程序的复杂度提高了23 2.无法准确预支结果24 3.使用场景:25 对扩展性要求较高的程序,26 通常是直接面向用户的,(所以需要根据需求随时调整)27 例如:qq,微信28 29 强调:30 对象不是凭空产生的,需要我们自己设计31 """32 """33 案例:34 面向对象与面向过程比较35 """36 """37 案例1:把大象装进冰箱38 面向过程:39 40 1.打开冰箱41 2.装入大象42 3.关闭冰箱 43 44 面向对象:45 找个具备装大象的技能的对象 46 结论1:47 在面向对象中程序员的角度发生改变,48 从具体的操作者变成了指挥者;49 50 强调:51 对象不是凭空产生的,需要我们自己设计52 记住:53 不是上所有程序都需要面向对象,得分析具体需求54 案例2:西天取经 55 如来有一堆破书要传出去,他没有自己干,而是找了五个对象帮他去干,56 如来只要负责控制调度的对象即可 ,57 如果某个对象发生变化,也不会影响其他的对象 , 扩展性 58 59 60 61 案例3:曹操吟诗62 喝酒吃肉,人生真爽 63 喝酒吃肉,人生几何64 对酒当歌,人生几何 65 66 面向过程,基本得写三次67 面向对象,修改一些功能即可 68 """69 """70 面向过程编程思想71 """72 """73 1.面向过程编程思想74 75 关注的核心是过程,76 过程就是一步一步的执行步骤,77 即先干啥在干啥78 2.优缺点: 79 优点:80 1.逻辑清晰,81 2.复杂问题简单化,流程化82 缺点:83 1.扩展性差,84 2.可维护性差85 86 3.# 应用87 对扩展性要求比较低得程序,88 例如:系统内核,git ,计算器89 记住:90 不是上所有程序都需要面向对象,得分析具体需求91 92 93 """
2.类和对象
2.1类和对象的概念
1 '''''' 2 """ 3 类和对象 4 这是OOP中的,最核心的两个概念 5 """ 6 """ 7 1.类: 8 即类型,是一种抽象概念 9 是一系列具备相同特征核心为的对象集合体10 """11 """12 2.对象:13 就是具体存在的某个事物,具备自己的特征和行为14 对象就是特征和技能的结合体15 """16 """17 类和对象的关系18 类包含一系列对象19 对象属于某个类20 在生活中先有对象,再有类21 而在程序中是先有类,才能有对象,22 我们必须告诉计算机这类的对象有什么特征和行为,23 从而根据这些信息总结出需要的内容,即,创建类24 """
2.2.如何创建类
1 '''''' 2 """ 3 创建类和对象 4 1.创建类 5 定义类的语法: 6 class 类的名称(参数): # (参数)可省略 7 # 类的内容,描述属性和技能 8 # 描述属性用变量 9 # 描述行为用函数10 类名称 书写规范:11 见名知意,名称是大驼峰命名法(首字母大写)12 注意:大驼峰就是单词首字母大写 , 大驼峰是第一个字母大写,小驼峰是第一个字母小写13 14 15 """16 17 18 class Person:19 a = 'dfsd'20 21 def studengt(self):22 print('dsfdsg')23 24 25 p = Person()26 p.studengt()
2.3如何创建对象
1 '''''' 2 """ 3 创建类和对象 4 2.创建对象: 5 创建对象的语法 6 class Person: 7 pass 8 # 创建对象(实例化) 9 p = Person()10 11 """12 13 14 class Person:15 a = 'dfsd'16 17 def studengt(self):18 print('dsfdsg')19 20 21 p = Person()22 p.studengt()
3.属性
3.1如何设计属性
1 '''''' 2 """ 3 1.如何设计属性? 4 1.属性可以写在类中, -- 公共的 5 代表所有对象公有的特征 6 2.属性可以现在对象中, -- (一般常用函数,独特的变量) -- 私有的 7 代表它是每个对象所独有 8 9 """10 class Person:11 # 1.定义在类中的属性12 is_need = 'est dinner'13 p = Person()14 # 2.定义在对象中--公有15 p.name = 'llx'16 p.age = 2417 p1 = Person()18 # 2.定义在对象中--私有19 p1.name = 'llw'20 p1.age = 1721 print(p.name,p.age,p.is_need)22 print(p.__dict__)23 print(p1.name,p1.age,p1.is_need)24 print(p1.__dict__)
3.2.属性的查找顺序
1 '''''' 2 """ 3 2.属性的查找顺序? 4 如果类中和对象中存在同样的属性,先访问对象 如果没有在访问类 5 """ 6 class Person: 7 school = 'oldboy' 8 # 2.对象中没有,才访问类中 9 is_need = 'eat dinner'10 def teacher(self,school,classer):11 self.school = school12 self.classer = classer13 p = Person()14 # 1.对象中有的,先访问对象15 p.school = 'bd'16 p.classer = 1017 print(p.school,p.classer,p.is_need)18 # 值 bd 10 eat dinner
3.3属性的增删改查
1 '''''' 2 """ 3 3.属性的增删改查: 4 1.增2.删3.改4.查 5 """ 6 class Person(): 7 is_need = 'eat dinner' 8 p = Person() 9 # 1.增10 # 对象变量名称.属性名称 = 属性值11 p.say = 'haha'12 p.name = 'wyf'13 print(p.say) # 值 haha14 # 2.删15 # del 对象变量名.属性名称16 # del p.name17 # print(p.name)18 # 值 AttributeError: 'Person' object has no attribute 'name'19 20 # 3.改21 # 对象变量名称.属性名称 = 新属性值22 p.say = '你好'23 print(p.say) # 你好24 # 4.查25 # 4.1查对象26 print(p.__dict__) # 值 {'say': '你好', 'name': 'wyf'}27 # 4.2查类28 print(p.__class__) #
4.初始化方法
1 '''''' 2 """ 3 __init__方法: 4 初始化方法 5 本质:就是一个函数 6 7 """ 8 """ 9 特点:10 1.生成对象的时候触发(自动执行__init__方法),即初始化11 2.定义的函数,不允许有返回值,其实是return None,规定如此...12 3.会自动将对象当做第一个参数传入,参数名称为self,self可以是别的名字,但是不建议修改功能(功能:用户给对象赋初始值)13 """14 class Person():15 # 1.生成对象的时候触发(自动执行__init__方法),即初始化16 # 3.会自动将对象当做第一个参数传入,参数名称为self(功能:用户给对象赋初始值)17 def __init__(self,name,age,gender):18 self.name = name19 self.name = age20 self.gender = gender21 22 # 2.定义的函数, 不允许有返回值, 其实是return None23 def teacher(self,name,age,gender,classer):24 super().__init__(self,name,age,gender)25 self.classer = classer26 def studengt(self,name,age,gender,study):27 super().__init__(self,name,age,gender)28 self.study = study29 p = Person('llx','25','298')30 p.classer = '16'31 p2 = Person('llw','18','555')32 p.study = '10'33 print(p.__dict__,p2.__dict__)34 # 值 {'name': '25', 'gender': '298', 'classer': '16', 'study': '10'} {'name': '18', 'gender': '555'}35 36 """37 # __init__方法二38 启动下方print()打印39 """40 class Person():41 42 def __init__(self,name,age,gender):43 self.name = name44 self.name = age45 self.gender = gender46 print('你好')47 print('启动')48 print('自运行')49 # 触发__init__自运行50 p = Person('llx','25','298') # 必须传参,否则会报错 # TypeError: __init__() missing 3 required positional arguments: 'name', 'age', and 'gender'51 print()52 """53 值:54 你好55 启动56 自运行57 """
5.绑定方法
5.1绑定方法-1.对象 2. 类(@classmethod)
1 """""" 2 """ 3 对象的精髓: 4 将数据和处理数据的函数整合到一起, 5 这样一来,拿到一对象, 6 就相当于同时拿到一个需要处理的数据,以及一个处理数据的函数 7 """ 8 """ 9 1.对象的绑定方法:10 1.默认情况下,11 类中的方法都是对象绑定方法,12 其特殊之处在于, 13 当使用对象调用自身函数时,会自动传入对象本身,作为第一个参数self14 class Person:15 def __init__(self):16 """17 # 练习:写一个学生类,具备一个打招呼的技能 要能输出自己的名字信息18 # # 119 # class Student:20 # def __init__(self,name):21 # self.name = name22 # def say(self,name,say):23 # super().__init__(self,name)24 # self.say = say25 # p = Student('llx')26 # p.say = '哈哈'27 # print(p.say)28 # print(p.__dict__) # {'name': 'llx', 'say': '哈哈'}29 # # 230 # class Student1:31 # def __init__(self,name):32 # self.name = name33 # def say(self):34 # print('%s说"haha"'%self.name)35 # p = Student1('llx')36 # p.say() # llx说"haha"37 # print(p.__dict__) # {'name': 'llx'}38 # print(type(p.say())) #39 """40 2.类绑定方法41 类绑定方法用@classmethod来装饰 # classmethod 分类方法42 特殊之处:不管用类调用还是对象调用,都会自动传入类本身,作为第一个参数43 44 # 应用45 单例模式中就会经常使用@classmethod46 @classmethod47 def singleton(cls):48 if not cls._instance:49 cls._instance = cls()50 return cls._instance51 """52 """53 3.判定什么时候绑定给类/对象?54 1.什么时候绑定给对象:当函数逻辑需要访问对象中的数据时55 2.什么时候绑定给类:当函数逻辑需要访问类中的数据时56 """57 # 案例:58 59 class Student2:60 student = 'old_boy'61 def __init__(self,name):62 self.name = name63 @classmethod64 def say_hi(cls):65 print(cls)66 67 p = Student2('llx')68 Student2.say_hi()69 print(p)70 71 print(Student2) # llx72 """73 74 <__main__.Student2 object at 0x0000015D0F4BA470>75 76 """
5.2与非绑定方法(不重要)(@startmethod)
1 """""" 2 """ 3 # 非绑定方法 -- 不常用 4 或叫静态方法,就是既不需要访问类的数据,也不需要访问对象的数据 5 语法@startcmethod 6 7 8 """ 9 class Student2:10 student = 'old_boy'11 def __init__(self,name):12 self.name = name13 @staticmethod14 def say_hi():15 print('hhhhhhh')16 p = Student2('llx')17 Student2.say_hi() # hhhhhhh
5.3案例-保存save,与获取
1 '''''' 2 """ 3 练习:为学生类添加一个save方法 一个get方法 4 save是将对象存储到文件中 5 get是从文件中获取对象 6 """ 7 import pickle 8 class Student: 9 def __init__(self,name):10 self.name = name11 def say_hi(self):12 print('name:',self.name)13 def save(self):14 with open(f'{self.name}.json','wb',)as f:15 pickle.dump(self,f)16 f.flush()17 @staticmethod18 def get(name):19 with open(f'{name}.json','rb')as f:20 res = pickle.load(f)21 f.flush()22 return res23 p = Student('llx')24 p.save()25 res = Student.get('llx')26 Student.get(res.name)27 print(Student.__name__) # Student28 print(Student.__class__) #29 print(Student.__dict__)30 # {'__module__': '__main__', '__init__': , 'say_hi': , 'save': , 'get': , '__dict__': , '__weakref__': , '__doc__': None, '__slotnames__': []}
6.案例,对象与类的使用实际应用
6.1对象之间的交互
1 """""" 2 """ 3 案例: 4 需求设计王者荣耀中的英雄类,每个英雄对象可以对其他英雄对象使用技能 5 具备以下属性 6 英雄名称,等级,血量 7 和Q_hurt,W_hurt,E_hurt 三个属性,表示各技能的伤害量 8 具备以下技能 9 Q W E10 三个技能都需要一个敌方英雄作为参数,当敌方血量小于等于0时角色死亡11 12 13 涉及到英雄对象14 属性:15 名字 等级grade 血量blood16 行为:17 Q W E18 需要一个英雄类19 20 """21 # 英雄类Hero22 class Hero:23 def __init__(self,name,grade,blood,Q_hurt,W_hurt,E_hurt):24 self.name = name25 self.grade = grade26 self.blood = blood27 self.Q_hurt = Q_hurt28 self.W_hurt = W_hurt29 self.E_hurt = E_hurt30 31 # attack 攻击 enemy敌人32 def attack(self, enemy, hurt):33 enemy.blood -= hurt34 if enemy.blood <= 0:35 print("%s已经被%s击杀了" % (enemy.name, self.name))36 def Q(self,enemy):37 print("%s已经被%s的Q技能击中,造成%s的伤害,血量剩余%s"%(enemy.name,self.name,self.Q_hurt,enemy.blood))38 self.attack(enemy,self.Q_hurt)39 def W(self,enemy):40 print("%s已经被%s的W技能击中,造成%s的伤害,血量剩余%s" % (enemy.name, self.name, self.W_hurt, enemy.blood))41 self.attack(enemy, self.W_hurt)42 def E(self,enemy):43 print("%s已经被%s的E技能击中,造成%s的伤害,血量剩余%s" % (enemy.name, self.name, self.E_hurt, enemy.blood))44 self.attack(enemy, self.E_hurt)45 46 p = Hero('孙悟空','20',1000,100,200,300)47 p2 = Hero('赵子龙','15',800,100,200,500)48 49 p.Q(p2)50 p.W(p2)51 p.E(p2)52 p2.Q(p)53 p2.W(p)54 p2.E(p)
6.2拓展
1 """""" 2 """ 3 案例: 4 需求设计王者荣耀中的英雄类,每个英雄对象可以对其他英雄对象使用技能 5 具备以下属性 6 英雄名称,等级,血量 7 和Q_hurt,W_hurt,E_hurt 三个属性,表示各技能的伤害量 8 具备以下技能 9 Q W E 10 三个技能都需要一个敌方英雄作为参数,当敌方血量小于等于0时角色死亡 11 12 13 涉及到英雄对象 14 属性: 15 名字 等级grade 血量blood 16 行为: 17 Q W E 18 需要一个英雄类 19 20 """ 21 import random 22 # 英雄类Hero 23 class Hero: 24 def __init__(self,name,grade,blood,hurt,q_hurt,w_hurt,e_hurt): 25 # self.name = name 26 # self.grade = grade 27 # self.blood = blood 28 # self.Q_hurt = Q_hurt 29 # self.W_hurt = W_hurt 30 # self.E_hurt = E_hurt 31 32 # 简便写法 33 lcs = locals() 34 lcs.pop('self') 35 self.__dict__.update(lcs) 36 37 # attack 攻击 enemy敌人 38 def attack(self, enemy): 39 enemy.blood -= self.hurt 40 print("%s已经被%s的普通技能技能击中,造成%s的伤害,血量剩余%s" % (enemy.name, self.name, self.hurt, enemy.blood)) 41 if enemy.blood <= 0: 42 print("%s已经被%s击杀了" % (enemy.name, self.name)) 43 def Q(self,enemy): 44 enemy.blood -= self.q_hurt 45 print("%s已经被%s的Q技能击中,造成%s的伤害,血量剩余%s"%(enemy.name,self.name,self.q_hurt,enemy.blood)) 46 if enemy.blood <= 0: 47 print("%s被%s使用Q技能击杀了" % (enemy.name, self.name)) 48 def W(self,enemy): 49 enemy.blood -= self.w_hurt 50 print("%s已经被%s的W技能击中,造成%s的伤害,血量剩余%s" % (enemy.name, self.name, self.w_hurt, enemy.blood)) 51 if enemy.blood <= 0: 52 print("%s被%s使用W技能击杀了" % (enemy.name, self.name)) 53 54 def E(self,enemy): 55 enemy.blood -= self.e_hurt 56 print("%s已经被%s的E技能击中,造成%s的伤害,血量剩余%s" % (enemy.name, self.name, self.e_hurt, enemy.blood)) 57 if enemy.blood <= 0: 58 print("%s被%s使用E技能击杀了" % (enemy.name, self.name)) 59 60 61 p = Hero('孙悟空',20,1000,50,100,200,300) 62 p2 = Hero('赵子龙',15,800,20,100,200,500) 63 p3 = Hero('二郎神',21,1000,50,100,200,400) 64 p4 = Hero('张飞',15,800,25,200,200,400) 65 66 # 从字典中随即拿出来一个值 67 68 while True: 69 # 把所有的攻击方法装到字典中,为了取一个随机数 70 funcs = {1:Hero.Q,2:Hero.W,3:Hero.E,4:Hero.attack} 71 func_index = random.randint(1,4) 72 # 随机选一种方法 73 func = funcs[func_index] 74 75 # 把所有英雄装到一个字典中 76 heros = {1:p,2:p2,3:p3,4:p4} 77 hero_index = random.randint(1,4) 78 # 随机选一个英雄 79 hero = heros[hero_index] 80 81 # 剩余的英雄{} 82 other_heros = {} 83 new_index = 1 84 for k,v in heros.items(): 85 if v != hero: 86 other_heros[new_index] = v 87 new_index += 1 88 89 # 从剩余的英雄中随机取一个英雄来挨打 90 other_index = random.randint(1,3) 91 enemy = other_heros[other_index] 92 93 # 开始战斗 94 func(hero,enemy) 95 if enemy.blood <= 0: 96 break 97 import time 98 time.sleep(0.5) 99 100 101 102 103 104 105 106 107 108 # li = [p,p2,p3,p4]109 # l = random.randint(1,len(li))110 # lsi = []111 # for k,v in enumerate(li,start=1):112 # if li.v != l:113 # lsi.append(v)114 # s = random.randint(1,len(lsi))115 # l.attack(s)116 # l.Q(s)117 # l.W(s)118 # l.E(s)