20.面向对象编程思想
# 面向对象编程思想 OOP 什么是面向对象 面向对象是一种编程思想,是前辈们总结出的经验,指导程序员如何编写出更好的程序 , 核心是对象,程序就是一系列对象的集合, 程序员负责调度控制这些对象来交互着完成任务: 案例:1 把大象装进冰箱 ? 面向过程: 1.打开冰箱 2.装入大象 3.关闭冰箱 面向对象: 找个具备装大象的技能的对象 在面向对象中程序员的角度发生改变,从具体的操作者变成了指挥者; 强调:对象不是凭空产生的,需要我们自己设计 案例: 西天取经 如来有一堆破书要传出去,他没有自己干,而是找了五个对象帮他去干, 如来只要负责控制调度的对象即可 , 如果某个对象发生变化,也不会影响其他的对象 , 扩展性 案例: 曹操吟诗 喝酒吃肉,人生真爽 喝酒吃肉,人生几何 对酒当歌,人生几何 ### 面向对象的三大优点 1.扩展性 2.灵活性 3.重用性 ### 缺点: 1.程序的复杂度提高了 2.无法准确预知结果 ### 使用场景 对扩展性要求较高的程序 ,通常是直接面向 用户的,例如:qq,微信 # 面向过程编程思想 关注的核心是过程,过程是就是一步一步的执行步骤,既先干啥在干啥 优点:逻辑清晰 , 复杂问题简单化,流程化 缺点: 扩展性差,可维护性差 使用场景: 对扩展性要求较低的程序例如:系统内核,git,计算器 记住:不是所有程序都要面向对象,得分析具体需求 # 类和对象 这是OOP中的最核心的两个概念 ## 类 既类型,类别 ,是一种抽象概念 是一系列具备相同特征和相同行为的对象的集合 ### 对象 就是具体存在的某个事物,具备自己的特征和行为 对象就是特征和技能的结合体 ### 类和对象的关系 类包含一系列对象 对象属于某个类 在生活中是先有对象再有类 而在程序中是先有类才能有对象,我们必须先告诉计算机这类的对象有什么特征有什么行为 总结出一个结论:在使用面向对象编程时,第一步就是思考需要什么样的对象,对象具备什么样的特征和行为,从而根据 这些信息总结出需要的类型 # 创建类和对象 定义类的语法 ```python class 类的名称: # 类中的内容 描述属性和技能 #描述属性用变量 #描述行为用函数 #类名称 书写规范 首先是见名知意 名称是大驼峰命名法 #驼峰就是单词首字母大写 , 大驼峰是第一个字母大写,小驼峰是第一个字母小写 ``` 创建对象的语法: ```python class Person: pass #创建对象 p = Person() ``` 属性的写法: ```python 属性可以写在类中 类中的属性,是所有对象公共的 也可以写在对象中 对象中的属性,是每个对象独特的(不一样的) 如果类中和对象中存在同样的属性,先访问对象 如果没有在访问类 练习: 描述一个老师类 需要包含 一个公共属性和 一个独特的属性 class Teacher: school = "oldboy" t1 = Teacher() t1.name = "jack" t1.age = 28 ``` 属性的增删改查 ```python 增加属性 对象变量名称.属性名称 = 属性值 删除属性 del 对象的变量名称.属性名称 修改 对象.属性 = 新的值 查看属性 访问的是对象的所有属性 print(对象.__dict__) 访问对象的类信息 print(对象.__class__) ``` # init方法 叫做初始化方法,本质上就是一个函数 特点1: 当实例化 对象时,会自动执行init方法 特点2:会自动将对象作为第一个参数传入,参数名称位self ,self可以是别的名字,但不建议改 功能:用户给对象赋初始值 练习:创建一个类具备几个属性,通过初始化方法来给他设置属性 ```python class Dog: def __init__(self,kind,color,age): self.kind = kind self.color = color self.age = age d1 = Dog("二哈","黑白",1) d1 = Dog("泰迪","棕色",2) 注意:该函数不能有任何返回值/.... 只能是None 规定如此.. ``` 对象的精髓就是讲数据和处理数据的函数整合到一起 ,这样一来拿到一个对象就同时拿到了需要处理的数据以及处理数据的函数 ## 对象的绑定方法 默认情况下类中的方法都是对象绑定方法 其特殊之处在于, 当使用对象调用该函数时会自动传入对象本身,作为第一个参数 当使用类名来调用时他就是一个普通函数,有几个参数就得传几个参数 练习:写一个学生类,具备一个打招呼的技能 要能输出自己的名字信息 ```python class Student: def __init__(self,name): self.name = name def say_hi(self): print("hello my name is %s" % self.name) ``` ## 类绑定方法 类绑定方法用@classmethod来装饰 特殊之处:不管用类还是对象调用,都会自动传入类本身,作为第一个参数 什么时候绑定给对象:当函数逻辑需要访问对象中的数据时 什么时候绑定给类:当函数逻辑需要访问类中的数据时 # 非绑定方法 或叫做静态方法,就是即不需访问类的数据,.也不需要访问对象的数据 语法:@staticmethod 不常用 l练习:为学生类添加一个save方法 一个get方法 save是将对象存储到文件中 get是从文件中获取对象 1.面向对象的概念 对比,面向过程的优缺点 以及使用场景 2.类和对象的概念 3.如何创建类和对象 4.如何设计属性 5.属性的查找顺序 6.初始化方法 7.绑定方法与非绑定方法 非绑定方法不重要

1.类的定义
class Student: pass # 创建对象的语法 调用类 既类名加括号 stu = Student() print(stu) print(Student)
2.属性的写法
class Person: """这是一个人类型""" desc = "都会吃饭" name = "张三分" # age = 20 # sex = "male" print("class run....") # p1 = Person() # print(p1.name) # p2 = Person() # print(p2.name) # p3 = Person() # p3.name = "李四" # p4 = Person() p4.name = "王五" # # print(p3.name) # print(p4.name) # 王五 print(p4.__dict__) # {'name': '王五'} print(p4.__class__) # <class '__main__.Person'> print(Person.__dict__) """ {'__module__': '__main__', '__doc__': '这是一个人类型', 'desc': '都会吃饭', 'name': '张三分', '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>} """
3.初始化对象的属性
class Teacher: school = "oldboy" # def init(obj, name, age): # obj.name = name # obj.age = age def __init__(self,name,age): print(self) self.name = name self.age = age t1 = Teacher("jack",18) print(t1.name) print(t1) # t1 = Teacher() # t2 = Teacher() # t3 = Teacher() # # # # print(t1.name) # print(t2.name) # print(t3.name) # Teacher.__init__(t1,"jack")
4.初始化方法不仅仅用于赋值
class PC: def __init__(self,kind,price,sys): self.kind = kind self.price = price self.sys = sys # 处理赋值以外的初始化操作 例如,启动BIOS啥啥的.... print("启动BIOS") print("启动系统分区") print("加载系统界面") print("启动成功....") p = PC("apple",15000,"macOS") print()
5.为对象定制行为
class Student: school = "oldgirl" 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(self) print("hello i am a student! my name:%s" % self.name) def a(self): pass stu1 = Student("jack",20,"male") stu2 = Student("rose",18,"female") # stu1.say_hi() # stu2.say_hi() # print(stu1) # stu2.say_hi() # Student.say_hi(stu1) print(type(Student.say_hi)) print(type(stu1.say_hi)) """ <class 'function'> <class 'method'> """
6,类的绑定方法
class OldBoyStudent: school = "oldboy" def __init__(self,name): self.name = name @classmethod def show_school(cls): # print(self.school) print(cls) @staticmethod def print_hello(): print("hello world") # OldBoyStudent.show_school(stu) # OldBoyStudent.show_school() # print(OldBoyStudent) stu = OldBoyStudent("jack") # stu.show_school() OldBoyStudent.print_hello() stu.print_hello()
7.练习
""" 练习:为学生类添加一个save方法 一个get方法 save是将对象存储到文件中 get是从文件中获取对象 """ import os import pickle import time class Student: def __init__(self,name): self.name = name def say_hi(self): print("name:",self.name) def save(self): with open(self.name,"wb") as f: pickle.dump(self,f) @staticmethod def get(name): with open(name,"rb") as f: obj = pickle.load(f) return obj # stu = Student("rose") # stu.save() # # # stu1 = Student("jack") # stu1.save() # obj = Student.get("rose") # print(obj.name) # # obj = Student.get("jack") # print(obj.name) print(Student.__name__)
8.对象交互练习
import random import time class Hero: def __init__(self,name,level,blood,att,q_hurt,w_hurt,e_hurt): # 简便写法 lcs = locals() lcs.pop("self") self.__dict__.update(lcs) 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.q_hurt print("%s对%s释放了Q 造成了%s的伤害 敌人剩余血量%s" % (self.name, enemy.name, self.q_hurt, enemy.blood)) if enemy.blood <= 0: print("%s被%s使用Q技能击杀了" % (enemy.name, self.name)) def W(self,enemy): enemy.blood -= self.w_hurt print("%s对%s释放了W 造成了%s的伤害 敌人剩余血量%s" % (self.name, enemy.name, self.w_hurt, enemy.blood)) if enemy.blood <= 0: print("%s被%s使用W技能击杀了" % (enemy.name, self.name)) def E(self,enemy): enemy.blood -= self.e_hurt print("%s对%s释放了E 造成了%s的伤害 敌人剩余血量%s" % (self.name,enemy.name,self.e_hurt,enemy.blood)) if enemy.blood <= 0: print("%s被%s使用E技能击杀了" % (enemy.name, self.name)) h1 = Hero("亚索",20,2000,100,600,0,1000) h2 = Hero("妲己",20,2000,100,600,500,1000) h3 = Hero("鲁班",20,1500,700,100,200,300) h4 = Hero("蔡文姬",20,2000,10,0,0,10) # # h1.attack(h2) # h2.Q(h1) # h2.E(h1) # h2.W(h1) #从字典中随机拿出一个值 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, 3: h3, 4: h4} 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)
浙公网安备 33010602011771号