zhukaijian

今日内容:


 

面向对象编程思想:OOP


 

什么是面向对象?

  • 面向对象是一种编程思想,是前辈们,总结的经验,指导程序员如何编写出更好的程序
  • 核心是对象,程序就是一系列对象的集合,程序员负责调度控制这些对象来交互着完成任务

案例: 1-把大象装进冰箱

  • 面向过程:
    • 1.打开冰箱
    • 2.装入大象
    • 3.关闭冰箱
  • 面向对象:
    • 找个具备装大象的技能的对象
    • 在面向对象中,程序员的角度发生改变,从具体的操作者变成了指挥者
注意: 对象不是凭空产生的,需要我们自己设计

案例: 2-西天取经

  • 如来有一堆破书要传出来,他没有自己干,而是找了五个对象帮他去干
  • 如来只要负责控制调度的对象即可
  • 如果某个对象发生变化,也不会影响其他的对象,扩展性与灵活性强

案例: 3-曹操吟诗

  • 需求1:喝酒吃肉,人生真爽
  • 需求2:喝酒吃肉,人生几何
  • 需求3:对酒当歌,人生几何

这种一直改需求的情况,将字拆成一个一个的,要用时拼起来就行

面向对象的三大优点:

  • 1.扩展性
  • 2.灵活性
  • 3.重用性

面向对象的缺点:

  • 1.程序的复杂度提高
  • 2.无法准确预知结果

使用场景:

  • 对扩展性要求较高的程序,通常是直接面向用户的,例如QQ与微信

注意点: 不是所有程序都要面向对象,得分析具体需求

面向过程编程思想:


 

关键的核心是过程,过程就是一步一步的执行步骤

 

面向过程优缺点:

  • 优点: 逻辑清晰,复杂问题简单化,流程化
  • 缺点: 扩展性差,可维护性差

使用场景:

  • 对扩展性要求较低的程序

例如: 系统内核,git,计算器

类和对象:


 

下面是OOP中的最核心的两个概念:

  • 类:

    • 即类型,类别,是一种抽象概念
    • 是一系列具备相同特征和行为的对象的集合
  • 对象:

    • 就是具体存在的某个事物,具备自己的特征与行为
    • 对象就是特征和技能的结合体

类和对象的关系:

  • 类包含一系列对象
  • 对象属于某个类
  • 在生活中是先有对象再有类
  • 而在程序中是先有类才能有对象,我们必须先告诉计算机这类的对象有什么特征,有什么行为

总结一个结论:

  • 在使用面向对象编程时,第一步就是思考需要什么样的对象,对象具备什么样的特征和行为,从而根据这信息总结出需要的类型

 

创建类和对象:


 

定义类的语法:

class 类的名称:

    # 类中的内容 描述属性和技能

    # 描述属性用变量

    # 描述行为用函数

   
# 类名称的书写规范: 首先是见名知意,名称是大驼峰命名法

# 驼峰就是单词首字母大写,大驼峰是第一个字母大写,小驼峰是第一个字母小写

类的定义:

class Student:

    pass# 创建对象的语法,调用类,即类名加括号

stu = Student()

print(stu)  # <__main__.Student object at 内存地址>

print(Student)  # <class\'__main__.Studet\'>

创建对象的语法:

class Person:

    pass# 创建对象
p = Person()

属性的写法:

  • 属性可以写在类中类中的属性,是所有对象公共的
  • 也可以写在对象中
  • 对象中的数,每个对象独特的(不一样的)
  • 如果类中和对象中存在同样的属性,先访问对象,如果没有,再访问类

练习: 描述一个老师类,需要包含一个公共属性和一个独特的属性

class Teacher:

    school = \'oldboy\'


t1 = Teacher()

t1.name = \'jack\'

t1.age = 18

​
t2 = Teacher()

t2.name = \'nick\'

t2.age = 28

属性的增删查改:

# 增加属性
# 对象变量名称.属性名称 = 属性值
# 删除属性
# del 对象的变量名称.属性名称
# 修改属性
# 对象.属性 = 新的值
# 查看属性(访问的是对象的所有属性)
print(对象.__dict__)
​
# __doc__是类的注释
print(对象.__class__)  # 访问对象的类信息

实例:

class Person1:

    name = \'朱质健\'

    age = 88

    sex = \'male\'

   
p1 = Person1()

print(p1.name)  # 朱质健

​
p2 = Person1()

print(p2.name)  # 朱质健
​
​
class Person2:

    desc = \'都能吃饭\'

​
p3 = Person2()

p3.name = \'bilibili\'

​
p4 = Person2()

p4.name = \'bangbangbang\'print(p3.name)  # bilibili

print(p4.name)  # bangbangbang

初始化对象的属性:

class Teacher:

    school = \'oldboy\'

    
t1 = Teacher()

t2 = Teacher()

​
init(t1,\'jason\',20)

init(t2,\'tank\',20)
​
​
class Teacher:

    school = \'oldboy\'

    
    def init(obj,name,age):

        obj.name = name

        obj.age = age

        
    def __init__(self,name,age)

        self.name = name

        self.age = age

​
t1 = Teacher(\'jason\',18)

Teacher.__init__(t1,\'jason\')

__init__方法:


 

它叫做初始化方法,本质上就是一个函数

  • 特点1:
    • 当实例化对象时,会自动执行__init__方法
  • 特点2:
    • 会自动将对象作为第一个参数传入,参数名称为self,self也可以是别的名字,不建议改

功能:

  • 用户给对象赋初始值

练习: 创建一个类,具备几个属性,通过初始化方法来给他设置属性

class Dog:

    def __init__(self,kind,color,age):

        self.kind = kind

        self.color = color

         self.age = age

       
d1 = Dog(\'二哈\',\'黑白\',1)

d2 = Dog(\'泰迪\',\'棕色\',2)

初始化方法不仅仅用于赋值:

class PC:

    def __init__(self,kind,price,sys):

        self.kind = kind

        self.price = price

        self.sys = sys

        # 除了赋值以外的初始化操作,例如:启动BIOS等
        print(\'启动BIOS\')

        print(\'启动系统分区\')

        print(\'加载系统界面\')

        print(\'启动成功>>>\')

        return None  # 这个函数不能有其他返回值,只能是None,规定如此        

为对象定制行为:

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(\'hello i am a student! my name is %s\'%self.name)

​
stu1 = Student(\'jack\',20,\'male\')

stu2 = Student(\'rose\',18,\'female\')

​
stu1.say_hi()

stu2.say_hi()

​
Student.say_hi(stu1)  # 等价于stu1.say_hi()

print(type(Student.say_hi))  # <class \'function\'>

print(type.stu1.say_hi)  # <class \'method\'>

总结:对象的精髓就是将数据和处理数据的函数整合到一起,这样一来,拿到一个对象就同时拿到了需要同时处理数据的函数

对象的绑定方法:


 

默认情况下类中的方法都是对象绑定方法

其特殊之处在于:

  • 当使用对象,调用该函数时会自动传入对象本身,作为第一个参数
  • 当使用类名,来调用时他就是一个普通函数,有几个参数就得传几个参数

练习:写一个学生类,具备一个打招呼的技能,要能输出自己的名字信息

class Student:

    def __init__(self,name):

        self.name = name

    def say_hi(self):

        print(\'hello my name is $s\'%self.name)

类的绑定方法:


 

类绑定方法用@classmethod来装饰

特殊之处:

  • 不管用类还是对象调用,都会自动传入类本身,作为第一个参数

什么时候绑定给对象:

  • 当函数逻辑需要访问对象中的数据时

什么时候绑定给类:

  • 当函数逻辑需要访问类中的数据时
class OldBoyStudent:

    school = \'oldboy\'

    def __init__(self,name):

        self.name = name

        
    @classmethod
    def show_school(cls):
print(cls) OldBoyStudent.show_school() # <class\'__main__.OldBoyStudent\'> print(OldBoyStudent) # <class\'__main__.OldBoyStudent\'>

非绑定方法:


 

或叫做静态方法,就是既不需要访问类的数据,也不需要访问对象的数据,而且它并不常用

语法:@staticmethod

class OldBoyStudent:

    school = \'oldboy\'

    def __init__(self,name):

        self.name = name

​
    @staticmethod
    def print_hello():

         print(\'hello world\')

序列化对象:


 

练习:为学生类添加一个save方法,一个get方法

  • save是将对象存储到文件中
  • get是从文件中获取对象
import pickle
​
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)  # rose

对象之间交互练习:


 

需求设计王者荣耀中的英雄类,每个英雄对象可以对其他英雄对象使用技能

具备以下属性:

  • 英雄名称,等级,血量和Q_hurt,W_hurt,E_hurt 三个属性,表示各技能的伤害量

具备以下技能:

  • Q W E
  • 三个技能都需要一个敌方英雄作为参数,当敌方血量小于等于0时角色死亡

代码实现(常规的简单方法):

import random
import time
​
class Hero:

    def __init__(self,name,level,blood,attack,q_hurt,w_hurt,e_hurt)

         # self.name = name
         # self.level = level
         # self.blood = blood
         # self.attack = attack
         # self.q_hurt = q_hurt
         # self.w_hurt = w_hurt
         # self.e_hurt = e_hurt
         
         lcs = locals()

         lcs.pop(\'self\')

         self.__dict__.updated(lcs)

     
    def attack(self,enemy):

        enemy.blood -= self.attack

         print(\'%s对%s释放了普通攻击,造成了%s伤害,敌人剩余血量%s\'%(self.name, enemy.name, self.attack, enemy_blood)

        if enemy.blood <= 0:

            print(\'%s被%s使用普通攻击击杀了\'%(enemy.name,self.name))

            
    def Q(self,enemy):

        enemy.blood -= self.q_hert

         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_hert

         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_hert

         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,200,600,0,50)

h2 = Hero(\'妲己\',20,2000,200,600,0,50)

​
# 常规攻击方式
h1.attack(h2)

h2.Q(h1)

h2.W(h1)

h2.E(h1)

英雄大乱斗(很有趣

分类:

技术点:

相关文章: