zoukankan      html  css  js  c++  java
  • day24

    一:面向过程 与 面向对象

    面向过程编程

    核心是过程二字,过程是解决问题的步骤,即:先干啥,后干啥

    基于该思想写程序就是在 设计一条条的流水线

    ​ 优点:复杂的问题流程化、进而简单化

    ​ 缺点:扩展性差

    面向对象编程

    核心是对象二字,对象是一个用来盛放数据与功能的容器

    基于该思想写程序就是在 整合程序

    ​ 优点:进行解耦合,可扩展性强

    ​ 缺点:编程复杂度高

    二:面向对象的实现思路

    1.基础版本

    众所周知:面向对象中,对象就是存放数据和功能的容器,用来存放相关的数据。

    现在先写一个基础版本的,非面向对象的学生数据和功能。

    此时,学生的数据和功能是完全分开的,没有关联的,只有在调用choose函数的时候,才会传入学生的信息。

    # 学生的数据
    stu_name = 'xxq'
    stu_age = 18
    stu_gender = 'male'
    
    
    # 学生的功能
    def choose(name, age, gender):
        print(f'学生:{name}正在选课,年龄:{age},性别:{gender}')
    
    
    choose(stu_name, stu_age, stu_gender)
    
    # 学生:xxq正在选课,年龄:18,性别:male
    

    2.基于面向对象的思想进行改写

    之前说到,对象就是一个数据和功能的容器,这里把学生的数据和功能放进一个字典里面。

    字典里可以以键值对的形式来存放学生的数据,但是函数只能通过调用来实现,所以还是只有一个雏形。

    # 学生的功能
    def choose(stu_self):
        print(f'学生:{stu_self["name"]}正在选课,年龄:{stu_self["age"]},性别:{stu_self["gender"]}')
    
    # 字典
    stu_obj = {
        'name': 'xxq',
        'age': 18,
        'gender': 'male',
        'choose': choose
    }
    
    stu_obj["choose"](stu_obj)
    
    # 学生:xxq正在选课,年龄:18,性别:male
    

    3.用类来实现

    在用类来实现之前,我们需要先来了解一下类和函数调用的区别。

    在定义一个函数之后,需要调用它,才会执行函数体的代码。

    而类则和函数不同,类体代码会在类定义阶段立刻执行,然后将产生的名字放到类的名称空间中。

    函数需要调用
    def call():
        print('调用了call函数')
    
    call()
    # 调用了call函数
    
    类不需要调用
    class Call:
        print('调用了Call类')
    
    # 调用了Call类
    

    现在有三个学生,他们的学校和功能(选课功能)相同,其余的姓名、性别、年龄不同,如果每个对象中都要写上学校和功能,就会出现代码冗余(同样的代码出现多次),因此,可以将他们公共的数据和功能放在同一个容器中,需要用到了就去拿一下即可,这就引入了 类 这个概念。

    例子 1 类的基本使用

    class Student:
        # 存放相同的数据
        school = "Tinghua"
    
        # 存放相同的功能
        def choose(self):
            print("正在选课")
    
    
    # 实例化3个学生对象
    stu_obj1 = Student()
    stu_obj2 = Student()
    stu_obj3 = Student()
    
    # 赋值学生1的特有数据
    stu_obj1.name = "张三"  # 相当于:stu1_obj1.__dict__["name"] = "张三"
    stu_obj1.age = 18
    stu_obj1.gender = "male"
    
    # 赋值学生2的特有数据
    stu_obj2.name = "李四"
    stu_obj2.age = 19
    stu_obj2.gender = "female"
    
    # 赋值学生3的特有数据
    stu_obj3.name = "王五"
    stu_obj3.age = 20
    stu_obj3.gender = "male"
    
    print(stu_obj1.__dict__)
    print(stu_obj2.__dict__)
    print(stu_obj3.__dict__)
    
    '''
    {'name': '张三', 'age': 18, 'gender': 'male'}
    {'name': '李四', 'age': 19, 'gender': 'female'}
    {'name': '王五', 'age': 20, 'gender': 'male'}
    '''
    

    例子 2 初始化方法的引入

    之前的用来类的方法来实现的面向对象的思想,进行的数据的整合,把相同的数据和功能放进了一个类中,然后不同的对象再赋不同的值,但是整体看上去还是太麻烦了,每个对象都要单独赋值,也存在很多代码冗余。因此,我们可以定义一个函数init来调用对象中的属性,直接以参数传递的形式来赋值。

    class Student:
        # 相同的数据
        school = "oldboy"
    
        # 相同的功能
        def choose(self):
            print("正在选课")
    
    
    # 实例化3个对象
    stu_obj1 = Student()
    stu_obj2 = Student()
    stu_obj3 = Student()
    
    
    # 定义一个函数来调用对象中的属性
    def init(obj, x, y, z):
        obj.name = x
        obj.age = y
        obj.gender = z
    
    
    init(stu_obj1, '张三', 18, 'male')
    init(stu_obj2, '李四', 19, 'female')
    init(stu_obj3, '王五', 20, 'male')
    
    print(stu_obj1.__dict__)
    print(stu_obj2.__dict__)
    print(stu_obj3.__dict__)
    
    '''
    {'name': '张三', 'age': 18, 'gender': 'male'}
    {'name': '李四', 'age': 19, 'gender': 'female'}
    {'name': '王五', 'age': 20, 'gender': 'male'}
    '''
    

    三:初始化方法

    例子 3 初始化方法的使用

    之前的init在类中其实是有一个__init__方法的,可以直接将调用对象作为一个参数自动传入,省去了很多麻烦,只需要传需要的参数就可以了

    class Student:
        # 相同的数据
        school = "oldboy"
    
        def __init__(obj, x, y, z):
            obj.name = x
            obj.age = y
            obj.gender = z
            # return None # 这里如果要加return 只能返回None
    
        # 相同的功能
        def choose(self):
            print("正在选课")
    
    # 调用类:
    # 1.创建一个空对象与类相关
    # 2.把空对象、'张三', 18, "male"一起传给__init__方法,完成对象的初始化
    # 3.赋值符号把初始化好的对象的内存地址绑定变量名stu_obj1
    # 实例化3个对象,并传值
    stu_obj1 = Student('张三', 18, "male")
    stu_obj2 = Student('李四', 19, "female")
    stu_obj3 = Student('王五', 20, "male")
    
    print(stu_obj1.__dict__)
    print(stu_obj2.__dict__)
    print(stu_obj3.__dict__)
    
    '''
    {'name': '张三', 'age': 18, 'gender': 'male'}
    {'name': '李四', 'age': 19, 'gender': 'female'}
    {'name': '王五', 'age': 20, 'gender': 'male'}
    '''
    

    四:属性查找

    在Python语法中,属性的查找是存在优先级的:先去对象自身找,找不到,再去进行实例化的类中找。

    class Student:
        school = 'Tinghua'
    
    stu_obj = Student()
    print(stu_obj.school)
    # Tinghua
    
    stu_obj.school = 'Peking'
    print(stu_obj.school)
    # Peking
    

    在上述代码中,定义了一个student类,其中定义了一个变量名school = 'Tinghua'

    实例化一个对象stu_obj之后,查找stu_objschool,找到的是Student类中的school,因此输出是Tinghua

    而在这之后,又单独给stu_objschool 单独赋值了Peking

    因此查找stu_obj'school,找到的是stu_obj对象中的school,因此输出是Peking

    五:绑定方法

    类中定义的函数是绑定给所有对象用的,绑定给谁就应该由哪个对象来调用
    对象.绑定方法()会把对象当作第一个参数传入
    类.函数()就是一个函数的玩法,没有自动传参的效果
    
    class Student:
        school = "oldboy"
    
        def __init__(obj, x, y, z):
            obj.name = x
            obj.age = y
            obj.gender = z
    
        def choose(self):
            print("%s 正在选课" % self.name)
    
    
    stu_obj1 = Student('张三', 18, "male")
    stu_obj2 = Student('李四', 19, "female")
    stu_obj3 = Student('王五', 20, "male")
    
    print(Student.choose)
    print(stu_obj1.choose)
    print(stu_obj2.choose)
    print(stu_obj3.choose)
    
    '''
    <function Student.choose at 0x000001AFAF5A68C8>
    <bound method Student.choose of <__main__.Student object at 0x000001AFB6690AC8>>
    <bound method Student.choose of <__main__.Student object at 0x000001AFB788B2E8>>
    <bound method Student.choose of <__main__.Student object at 0x000001AFB78FB6A0>>
    '''
    
  • 相关阅读:
    qml+opencv(二),实现人脸检测
    CPU满格的元凶,这回是由于QTimer引起的(默认interval是0,太猛)
    Qt文档系统分析(解释Qt文档的生成工具与过程)
    2015 最受开发者欢迎的开发工具和服务(摘录对自己有用的)
    RAD Studio 10 自带Demo代码汇总说明
    ACE 容器之三 ACE_Unbounded_Queue的使用
    开发快很重要——如果只看法语或者产品结果C++似乎很强大,但是参与这个C++的开发过程,就会感觉到这种痛苦(Google也是这个看法)
    我是觉得创业永远不晚 但是绝对要谨慎,不是破釜沉舟就一定能赢的(不用拿工资啊 吃喝拉撒在公司报账就好了)
    人生的成功与否,真的是以天来计算啊——时间永远都是最宝贵的!
    thiscall仅仅应用于“C++”成员函数(this指针存放于CX寄存器,参数从右到左压)
  • 原文地址:https://www.cnblogs.com/xuexianqi/p/13433682.html
Copyright © 2011-2022 走看看