首页 > 其他分享 >面向对象、面向过程、类与对象

面向对象、面向过程、类与对象

时间:2024-05-08 20:47:59浏览次数:19  
标签:__ obj name val 对象 self 面向对象 面向 print

【一】人狗大战

【1】人狗大战小游戏描述

  • 人可以打狗,狗掉血,狗可以咬人,人掉血

【2】人狗大战小游戏实现

(0)分析

  • 人的属性
    • 人的名字
    • 人的类型
    • 人的年龄
    • 人的攻击力
    • 人的生命值
  • 狗的属性
    • 狗的名字
    • 狗的类型
    • 狗的攻击值
    • 狗的生命值

(1)定义人和狗的参数

  • 方式一:使用字典定义属性
dog1 = {
    'name': '小黑',
    'type': '田园犬',
    'attack_val': 30,
    'life_val': 200
}
dog2 = {
    'name': '小白',
    'type': '恶霸犬',
    'attack_val': 180,
    'life_val': 500
}
person1 = {
    'name': '小龙',
    'type': '猛男',
    'attack_val': 10,
    'life_val': 1000
}
  • 方式二:封装成函数,减少代码冗余
# 将人类的属性用函数声明
def get_person(name, gender, age, t_type, attack_val, life_val):
    '''
    :param name: 人的名字
    :param gender: 人的性别
    :param age: 人的年龄
    :param t_type: 人的类型
    :param attack_val: 攻击值
    :param life_val: 生命值
    :return:
    '''
    data_dict = {
        'name': name,
        'gender': gender,
        'age': age,
        't_type': t_type,
        'attack_val': attack_val,
        'life_val': life_val
    }
    return data_dict


# 将狗的属性用函数声明
def get_dog(name, t_type, attack_val, life_val):
    '''
    :param name: 狗的名字
    :param t_type: 狗的类型
    :param attack_val: 攻击值
    :param life_val: 生命值
    :return: 
    '''
    data_dict = {
        'name': name,
        't_type': t_type,
        'attack_val': attack_val,
        'life_val': life_val
    }
    return data_dict

(2)大战功能的实现

# 定义专门用来描述人和狗的函数(最好单独编写)
def get_person(name, gender, age, t_type, attack_val, life_val):
    data_dict = {
        'name': name,
        'gender': gender,
        'age': age,
        't_type': t_type,
        'attack_val': attack_val,
        'life_val': life_val
    }
    return data_dict


def get_dog(name, t_type, attack_val, life_val):
    data_dict = {
        'name': name,
        't_type': t_type,
        'attack_val': attack_val,
        'life_val': life_val
    }
    return data_dict


p1 = get_person('dream', 'male', 18, '猛男', 800, 1000)
p2 = get_person('hope', 'female', 28, '淑女', 5, 100)
dog1 = get_dog('小黑', '松狮犬', 300, 500)
dog2 = get_dog('小白', '泰迪犬', 50, 200)


# 定义一个函数用来描述人和狗的攻击行为
def dog_attack(dog_obj, person_obj):
    """
    :param dog_obj: 接收一条狗
    :param person_obj: 接收一个人
    """
    # 使用最简答的掉血逻辑  血量减去对方攻击力
    print('当前人的血量是:%s' % person_obj.get('life_val'))
    person_obj['life_val'] -= dog_obj.get('attack_val')
    print("""狗:%s 咬了人:%s 一口 人掉血:%s 剩余血量:%s""" % (
        dog_obj.get('name'), person_obj.get('name'), dog_obj.get('attack_val'), person_obj['life_val']))


def person_attack(person_obj, dog_obj):
    """
    :param person_obj: 接收一个人
    :param dog_obj: 接收一条狗
    """
    print('当前狗的血量是:%s' % dog_obj.get('life_val'))
    dog_obj['life_val'] -= person_obj.get('attack_val')
    print("""人:%s 锤了狗:%s 一下 狗掉血:%s 剩余血量:%s""" % (
        person_obj.get('name'), dog_obj.get('name'), person_obj.get('attack_val'), dog_obj['life_val']))


# 狗咬人
dog_attack(dog2, p1)
print(p1)
# 人锤狗
person_attack(p2, dog1)
print(dog1)

'''人调用了狗的攻击动作'''
dog_attack(p1, dog1)
'''狗调用了人的攻击工作'''
person_attack(dog2, p2)

【3】人狗大战小游戏优化

"""如何做到只有人可以调用人的攻击动作 狗调用狗的攻击动作"""


# 其实就是想让人的数据跟人的功能绑定 狗的数据跟狗的功能绑定
def get_person(name, gender, age, t_type, attack_val, life_val):
    # 将人的攻击动作放在产生人的函数内
    def person_attack(person_obj, dog_obj):
        """
        :param person_obj: 接收一个人
        :param dog_obj: 接收一条狗
        """
        print('当前狗的血量是:%s' % dog_obj.get('life_val'))
        dog_obj['life_val'] -= person_obj.get('attack_val')
        print("""人:%s 锤了狗:%s 一下 狗掉血:%s 剩余血量:%s""" % (
            person_obj.get('name'), dog_obj.get('name'), person_obj.get('attack_val'), dog_obj['life_val']))

    data_dict = {
        'name': name,
        'gender': gender,
        'age': age,
        't_type': t_type,
        'attack_val': attack_val,
        'life_val': life_val,
        'person_attack': person_attack
    }
    return data_dict


def get_dog(name, t_type, attack_val, life_val):
    def dog_attack(dog_obj, person_obj):
        """
        :param dog_obj: 接收一条狗
        :param person_obj: 接收一个人
        """
        # 使用最简答的掉血逻辑  血量减去对方攻击力
        print('当前人的血量是:%s' % person_obj.get('life_val'))
        person_obj['life_val'] -= dog_obj.get('attack_val')
        print("""狗:%s 咬了人:%s 一口 人掉血:%s 剩余血量:%s""" % (
            dog_obj.get('name'), person_obj.get('name'), dog_obj.get('attack_val'), person_obj['life_val']))

    data_dict = {
        'name': name,
        't_type': t_type,
        'attack_val': attack_val,
        'life_val': life_val,
        'dog_attack': dog_attack
    }
    return data_dict


p1 = get_person('dream', 'male', 18, '猛男', 800, 1000)
p2 = get_person('hope', 'female', 28, '淑女', 10, 100)
dog1 = get_dog('小黑', '松狮犬', 300, 500)
dog2 = get_dog('小白', '泰迪犬', 50, 200)
p1['person_attack'](p1, dog1)
dog1['dog_attack'](dog1, p2)

【4】小结

  • 上述操作其实就是将数据与功能进行绑定
  • 不再是所有的数据都可以调用任意的功能
  • 将上述数据与功能整合到一起的操作其实就是面向对象编程的思想

【二】什么是面向过程

【1】面向过程

  • 关键就在于过程,意思就是将程序流程化
  • 过程就是流水线,用到哪个功能就去写哪个功能。分步骤解决问题
  • 过程指的是解决问题的步骤,即先干什么再干什么...
  • 面向过程的设计就好比精心设计好一条流水线,是一种机械式的思维方式。

【2】优点

  • 复杂度的问题流程化,进而简单化(一个复杂的问题,分成一个个小的步骤去实现,实现小的步骤将会非常简单)
  • 逻辑清晰

【3】缺点

  • 一套流水线或者流程就是用来解决一个问题,生产汽水的流水线无法生产汽车,即便是能,也得是大改,改一个组件,牵一发而动全身。

【三】什么是面向对象

【1】面向对象

  • 面向过程,核心在于“对象”二字
  • 对象的终极奥义就是将程序 “整合”
  • 对象就是 “容器” ,用来盛放数据与功能
  • 面向对象就相当于上帝,在上帝的视角,人是对象,动物是对象,石头是对象,水是对象,山是对象.....存在的可以扩充,不存咋的可以创造。

(1)面向对象设计

  • 面向对象的设计就好比我们要设计一个小校园模拟器,我们需要在校园中创造各种生活场景,包括上课、做饭、打球等等。

  • 这些场景对应的角色就是对象,比如老师、学生、运动员、厨师等。

  • 而每一个角色都会对应其具有的责任和功能

    • 比如一个学生具有姓名、年龄、性别、所在班级等。
    • 学生还有能做的活动,读书、写作、跑步、打篮球等。
    • 比如一个老师可以教书、批改作业等。
    • 比如运行员可以参加训练和比赛等。
  • 当我们的角色和功能构建好以后,我们又需要创建几个学生、一些老师和运行员,让他们进行各项活动。

    • 比如一个学生可以上课、写作业、运动;
    • 比如一个老师可以教课、批改作业;
    • 比如一个运动员可以训练、参加比赛

【2】优缺点

(1)面向对象优点

  • 解决了程序的扩展性。
  • 对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。

(2)面向对象缺点

  • 编程的复杂度远高于面向过程,不了解面向对象而立即上手基于它设计程序,极容易出现过度设计的问题。
    • 一些扩展性要求低的场景使用面向对象会徒增编程难度,比如管理linux系统的shell脚本就不适合用面向对象去设计,面向过程反而更加适合。
  • 无法向面向过程的程序设计流水线式的可以很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题,即便是上帝也无法准确地预测最终结果。
    • 于是我们经常看到对战类游戏,新增一个游戏人物,在对战的过程中极容易出现阴霸的技能,一刀砍死3个人,这种情况是无法准确预知的,只有对象之间交互才能准确地知道最终的结果。

【四】类与对象

【零】什么是类

  • 类即类别、种类,是面向对象设计最重要的概念,对象是特征与技能的结合体,而类则是一系列对象相似的特征与技能的结合体

【1】类的属性

class Student(object):
     # 数据属性
     school_name = "清华"

     # 函数属性
     def read(self):
         age = 18
         # self : 表示对象自己本身,
         print(f"当前学校是 {self.school_name}")

student = Student()
print(student)  # <__main__.Student object at 0x000001F2074B1340>
# 想用类里面的属性和方法
print(student.school_name) # 清华
print(student.read()) 
# 当前学校是 清华
# None

【2】查看类的名称空间

print(Student.__dict__)
# # {'__module__': '__main__', 'school_name': '清华', 'read': <function Student.read at 0x000001906F653A30>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None}

【3】实例化类得到对象

# 得到的对象每一次都是新的
student_one = Student()
student_two = Student()

print(id(student_one))
# 1853725687376
print(id(student_two))
# 1853726139200

【4】如何修改对象的属性

(1)通过类的名称空间修改属性

[1]类的名称空间不允许修改属性
class Student(object):
    # 数据属性
    school_name = "清华"

    # 函数属性
    def read(self):
        age = 18
        # self : 表示对象自己本身,
        print(f"当前学校是 {self.school_name}")

space_class = Student.__dict__
print(space_class, type(space_class))  # <class 'mappingproxy'>
print(space_class['school_name']) # 清华
print(space_class.get('school_name')) # 清华

Student.__dict__['school_name'] = '北大'
print(Student.__dict__['school_name']) #报错

(2)修改对象的属性

[1]通过类的名称空间修改属性
class DreamStudent(object):
    school = '梦想学城'

    def read_books(self):
        print('is reading books')

    def write_nodes(self):
        print('is write nodes')

    def running(self):
        print('is running')


obj1 = DreamStudent()  # 目前对象没有自己独有的属性
obj2 = DreamStudent()  # 目前对象没有自己独有的属性
print(obj1.__dict__)  # 大白话就是给字典添加键值对  {}
print(obj2.__dict__)  # 大白话就是给字典添加键值对  {}
'''方案1:逐步给对象添加独有的数据'''
obj1.__dict__['name'] = 'chosen'  # obj1.name = 'chosen'
obj1.__dict__['age'] = 18  # obj1.age = 18
obj1.__dict__['gender'] = 'male'  # obj1.gender = 'male'

obj2.__dict__['name'] = 'hope'  # obj2.name = 'hope'
obj2.__dict__['age'] = 2  # obj2.age = 2
obj2.__dict__['gender'] = 'female'  # obj2.gender = 'female'
print(obj1.__dict__,
      obj2.__dict__)  # {'name': 'dream', 'age': 18, 'gender': 'male'} {'name': 'hope', 'age': 2, 'gender': 'female'}
print(obj1.name)  # chosen
print(obj2.name)  # hope
[2]封装成函数
class DreamStudent(object):
    school = '梦想学城'

    def read_books(self):
        print('is reading books')

    def write_nodes(self):
        print('is write nodes')

    def running(self):
        print('is running')


obj1 = DreamStudent()  # 目前对象没有自己独有的属性
obj2 = DreamStudent()  # 目前对象没有自己独有的属性
print(obj1.__dict__)  # 大白话就是给字典添加键值对  {}
print(obj2.__dict__)  # 大白话就是给字典添加键值对  {}
'''方案2:将冗余的添加步骤封装成函数'''


def init(obj, name, age, gender):
    obj.name = name  # obj.__dict__['name'] = name
    obj.age = age  # obj.__dict__['age'] = age
    obj.gender = gender  # obj.__dict__['gender'] = gender


init(obj1, 'chosen', 18, 'male')
init(obj2, 'hope', 28, 'female')
print(obj1.name)
print(obj2.name)
[3]封装成类的方法
class DreamStudent(object):
    school = '梦想学城'

    def read_books(self):
        print('is reading books')

    def write_nodes(self):
        print('is write nodes')

    def running(self):
        print('is running')

    def set_info(obj, name, age, gender):
        obj.name = name  # obj.__dict__['name'] = name
        obj.age = age  # obj.__dict__['age'] = age
        obj.gender = gender  # obj.__dict__['gender'] = gender


'''方案3:简单的封装成函数没有提现出面向对象整合的精髓>>>:将函数写到类中去'''
obj1 = DreamStudent()
obj2 = DreamStudent()
DreamStudent.set_info(obj1,'chosen',18,'male')
DreamStudent.set_info(obj2,'hope',28,'female')
print(obj1.name)  # chosen
print(obj2.name)  # hope
[4]类的魔法方法__init__
  • 想在实例化的过程中就为三位学生定制各自独有的数据:
    • 姓名,性别,年龄,需要我们在类内部新增一个__init__方法,如下
class DreamStudent(object):
    school = '梦想学城'

    # 该方法会在对象产生之后自动执行,专门为对象进行初始化操作,可以有任意代码,但一定不能返回非None的值
    def __init__(self, name, sex, age):
        self.name = name
        self.sex = sex
        self.age = age

    def read_books(self):
        print('%s is reading books' % self.name)

    def write_nodes(self):
        print('%s is write nodes' % self.name)

    def running(self):
        print('%s is running' % self.name)

    def choose(self):
        print('%s is choosing a course' % self.name)
  • 然后重新实例出三位学生
s1 = DreamStudent('梦梦', '男', 18)  # 先调用类产生空对象s1,然后调用DreamStudent.__init__(s1,'梦梦','男',18)
s2 = DreamStudent('萌萌', '女', 30)
s3 = DreamStudent('朦朦', '女', 20)
  • 单拿stu1的产生过程来分析

  • 调用类会先产生一个空对象stu1

  • 然后将stu1连同调用类时括号内的参数一起传DreamStudent.__init__(stu1,’梦梦’,’男’,18)

def __init__(self, name, sex, age):
    self.name = name  # stu1.name = '梦梦'
    self.sex = sex    # stu1.sex = '男'
    self.age = age    # stu1.age = 18
  • 实例化类会产生对象的名称空间,同样可以用__dict__查看
class DreamStudent(object):
    school = '梦想学城'

    # 该方法会在对象产生之后自动执行,专门为对象进行初始化操作,可以有任意代码,但一定不能返回非None的值
    def __init__(self, name, sex, age):
        self.name = name
        self.sex = sex
        self.age = age

    def read_books(self):
        print('%s is reading books' % self.name)

    def write_nodes(self):
        print('%s is write nodes' % self.name)

    def running(self):
        print('%s is running' % self.name)

    def choose(self):
        print('%s is choosing a course' % self.name)


stu1 = DreamStudent('梦梦', '男', 18)
print(stu1.__dict__)
# {'name': '梦梦', 'sex': '男', 'age': 18}
  • 至此,我们造出了三个对象与一个类,对象存放各自独有的数据,类中存放对象们共有的内容

【5】属性查找顺序

class BaseStudent(object):
    school_name = '北大'


class Student(BaseStudent):
    # 数据属性
    # school_name = "清华"

    # 实例化对象的时候就会被触发 Student() 一定会报错
    def __init__(self, name, age, gender):
        # self 就是这个类的对象本身
        self.name = name
        self.age = age
        self.gender = gender

    def set_info(self,class_id):
        self.class_id = class_id
    # 函数属性
    def read(self):
        print(f"当前学校是 {self.school_name}")
        print(f"当前学生姓名是 {self.name}")
        print(f"当前学生年龄是 {self.age}")
        print(f"当前学生性别是 {self.gender}")
        print(f"当前学生课程ID是 {self.class_id}")

    def write(self):
        print(f"当前学生 :>>> {self.name} 可以写作业!")


# 初始化类得到对象
student = Student(name='dream', age=18, gender='male')
# print(student.name)
student.set_info(class_id=1)
student.read()
student.name = 'opp'  # student.__dict__['name'] = 'opp'
print(student.name)

# 属性查找顺序
print(student.name)
print(student.school_name)
# 查找顺序
# 首先在自己的对象中查找
# 自己找不到就去父类里面找
# 如果父类里面找不到,就去基类里面找
# 如果基类里面也没有,就去 object 里面找
# 如果还是找不到则报错

【6】列表特性回顾

# 类型list就是类
print(type(list))
# <class 'type'>

# 实例化的到3个对象 list_one,list_two,list_three
list_one = list([1, 2, 3])
list_two = list(['a', 'b', 'c'])
list_three = list(['x', 'y'])

# 三个对象都有绑定方法append,是相同的功能,但内存地址不同
print(list_one.append)
# <built-in method append of list object at 0x0000022B219CDA80>
print(list_two.append)
# <built-in method append of list object at 0x0000022B21A0B880>
print(list_three.append)
# <built-in method append of list object at 0x0000022B21A16FC0>

# 操作绑定方法l1.append(4)
# 就是在往l1添加4,绝对不会将4添加到l2或l3

# 等同于list.append(list_one,4)
list_one.append(4)
print(list_one)
# [1, 2, 3, 4]

print(list_two)
# ['a', 'b', 'c']

print(list_three)
# ['x', 'y']

【五】类的属性扩展

# 【一】定义类
class Animal(object):
    animal_name = ''


class Duck(Animal, object):
    '''
    这是一条注释
     '''

    # 这是一条注释
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def speak(self):
        print(f"这是一只鸭子 叫 {self.name} 已经 {self.age} 岁了!")


def speak(obj):
    print(f"obj.__class__.__name__ :>>>> {obj.__class__.__name__}")
duck = Duck(name='唐老鸭', age=2)
speak(obj=duck)
# 【二】属性介绍
# 【1】获取当前类的名字
print(Duck.__name__)
# 【2】获取类中的文档字符串
print(Duck.__doc__)
# 【3】获取类的父类
print(Duck.__base__)  # <class '__main__.Animal'>
# 【4】获取类的所有父类
print(Duck.__bases__)  # (<class '__main__.Animal'>, <class 'object'>)
# 【5】获取当前类的名称空间
print(Duck.__dict__)
# 【6】获取类定义所在的模块名
print(Duck.__module__)  # __main__

标签:__,obj,name,val,对象,self,面向对象,面向,print
From: https://www.cnblogs.com/chosen-yn/p/18180807

相关文章

  • 面向对象的三大特性、封装的介绍及属性、装饰器property、员工管理系统
    【一】面向对象的三大特性封装:封装指的就是把数据与功能都整合到一起继承多态【二】什么是封装封装是对具体对象的一种抽象意思就是将某部分功能和代码隐藏起来,在程序外边看不到,只能在程序内部使用【三】为什么要封装?封装数据的主要原因是:保护隐私(把不想别人......
  • 20.面向对象【四】
    【一】抽象类抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化#所有继承父类的子类必须重写父类的某些方法,这个父类就叫抽象类importabcclassAnimal(metaclass=abc.ABCMeta):def__init__(self,color,foot):self.color=colorself.f......
  • Java面向对象04——三大特性之多态
    多态1、什么是多态在Java中,多态是面向对象编程中的一个重要概念,它允许不同类型的对象对同一方法进行不同的实现。具体来说,多态性指的是通过父类的引用变量来引用子类的对象,从而实现对不同对象的统一操作。2、多态实现的条件在Java中,要实现多态性,就必须满足以下条件:继承关......
  • 19.面向对象【三】
    【一】继承1)概念继承是一种创建新类的方式,新建的类可以继承一个或多个类的属性可以继承父类的所有属性和方法,实现代码的去重classStudent(School):#继承的类叫父类School#新建的类叫子类Student2)单继承classPerson(object):height=170weight=7......
  • 如何判断一个js对象是否存在循环引用
    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助一、背景在前端JSON.stringfy是我们常用的一个方法,可以将一个对象序列化。例如将如下对象序列化constperson={name:'kalory',age:18}JSON.stringfy(person)//结果'{"name":"kalory","age":18}'将一......
  • 【OpenVINO™】使用OpenVINO™ C# API 部署 YOLO-World实现实时开放词汇对象检测
    YOLO-World是一个融合了实时目标检测与增强现实(AR)技术的创新平台,旨在将现实世界与数字世界无缝对接。该平台以YOLO(YouOnlyLookOnce)算法为核心,实现了对视频中物体的快速准确识别,并通过AR技术将虚拟元素与真实场景相结合,为用户带来沉浸式的交互体验。在本文中,我们将结合OpenVINO......
  • C#中面向对象的一些基础概念
    案例所创建的.cs如下:OOP--ObjectOrientedProgramming实例化类baseclassbc=newbaseclass();subclasssc=newsubclass();bc.Func();sc.Func();里氏转换子类对象可以直接赋值给父类变量子类可以调用父类对象,但是父类只有调用自己父类中如果是子类对象,则......
  • Teamcenter之《BMIDE修改业务对象图标》
    准备图标图标可以在iconfonthttps://www.iconfont.cn/下载规格为16*16png即可重命名一个合适的名字,这里下载了两个,一个做为Item,一个为ItemRevision,如图:打开BMIDE上传图标找到对应类型修改并部署需要设置Item,itemRevision(有需要表单类型也可以修改图标)登陆查......
  • openGauss 导出全局对象
    导出全局对象openGauss支持使用gs_dumpall工具导出所有数据库公共的全局对象,包含数据库用户和组,表空间及属性(例如:适用于数据库整体的访问权限)信息。操作步骤以操作系统用户omm登录数据库主节点。使用gs_dumpall导出表空间对象信息。gs_dumpall-Uomm-f/home/omm/backu......
  • Hyperf 的AOP 面向切面编程实战
    概念AOP为 AspectOrientedProgramming 的缩写,意为:面向切面编程,通过动态代理等技术实现程序功能的统一维护的一种技术。AOP是OOP的延续,也是Hyperf中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的......