zoukankan      html  css  js  c++  java
  • 面向对象编程

    一 对象的概念

      面向对象“的核心是“对象”二字,而对象的精髓在于“整合“

      所有的程序都是由”数据”与“功能“组成,因而编写程序的本质就是定义出一系列的数据,然后定义出一系列的功能来对数据进行操作。在学习”对象“之前,程序中的数据与功能是分离开的,

      

      在学习了“对象”之后,我们就有了一个容器,该容器可以盛放数据与功能,所以我们可以说:对象是把数据与功能整合到一起的产物,或者说”对象“就是一个盛放数据与功能的容器/箱子/盒子。

      面向对象编程就是要造出一个个的对象,把原本分散开的相关数据与功能整合到一个个的对象里

      优点:方便使用,提高程序的解耦合程度,提升了程序的可扩展性

    二 类

      在学习面向对象编程之前我们还要先知道类的概念

      2.1 什么是类

        类即类别/种类,是面向对象分析和设计的基石,如果说对象是用来存放数据与功能的容器,那么类则是用来存放多个对象相同的数据与功能的容器。

        如果多个对象有相似的数据与功能,那么该多个对象就属于同一种类。

                                                                                              类

    三 面向对象编程

      3.1 类的定义

        面向对象的基本思路就是把程序中要用到的、相关联的数据与功能整合到对象里,然后再去使用,我们举个例子

    # 学生1:
        数据:
            学校=清华大学
            姓名=李建刚
            性别=男
            年龄=28
        功能:
            选课
    
    # 学生2:
        数据:
            学校=清华大学
            姓名=王大力
            性别=女
            年龄=18
        功能:
            选课
    
    # 学生3:
        数据:
            学校=清华大学
            姓名=牛嗷嗷
            性别=男
            年龄=38
        功能:
            选课

        首先我们可以定义一个类

    class Student:
        school = '清华'
    
        # 2、功能的定义
        def tell_stu_info(stu_obj):
            print('学生信息:名字:%s 年龄:%s 性别:%s' %(
                self.stu_name,
                self.stu_age,
                self.stu_gender
            )) 
    
        def choose(self): print('%s is choosing a course' %self.name)                            

        类体中最常见的是变量与函数的定义,但是类体其实是可以包含任意其他代码的

        注意:类体代码是在类定义阶段就会立即执行,会产生类的名称空间

        可以打印Student.__dict__来查看类这个容器内盛放的东西

      3.2 类的调用再产生对象

    stu1_obj=Student() #没调用一次类就会产生一个学生对象
    stu2_obj=Student()
    stu3_obj=Student()

        如此stu1_obj、stu2_obj、stu3_obj全都一样了(只有类中共有的内容,而没有各自独有的数据),想在调用的过程中就为三位学生定制各自独有的数据:姓名,性别,年龄,需要我们在类内部新增一个__init__方法,如下

    class Student:
        school = '清华'
    
        def __init__(obj,x,y,z):
            obj.stu_name=x 
            obj.stu_age=y  
            obj.stu_gender=z 
            # return None
    
        # 2、功能的定义
        def tell_stu_info(stu_obj):
            print('学生信息:名字:%s 年龄:%s 性别:%s' %(
                    self.stu_name,
                    self.stu_age,
                    self.stu_gender
            ))
            
        def choose(self): 
            print('%s is choosing a course' %self.name)

         关于_init_方法 

        1、会在调用类时自动触发执行,用来为对象初始化自己独有的数据

        2、__init__内应该存放是为对象初始化属性的功能,但是是可以存放任意其他代码,想要在类调用时就立刻执行的代码都可以放到该方法内

        3、__init__方法必须返回None

    stu1_obj=Student('egon',18,'male')
    stu2_obj=Student('lili',19,'female')
    
    print(stu1_obj.__dict__)
    print(stu2_obj.__dict__)
    
    # {'stu_name': 'egon', 'stu_age': 18, 'stu_gender': 'male'}
    # {'stu_name': 'lili', 'stu_age': 19, 'stu_gender': 'female'}

         调用类的过程发生了三件事

        1、先产生一个空对象

        2、python会自动调用类中的__init__方法然将空对象已经调用类时括号内传入的参数一同传给__init__方法

        3、返回初始完的对象

        单拿stu1_obj的产生过程来分析,调用类会先产生一个空对象stu1_obj,然后将stu1_obj连同调用类时括号内的参数一起传给Student.__init__(stu1_obj,’egon’,18,;male')

      3.3 属性的访问

        在类中定义的名字,都是类的属性,细说的话,类有两种属性:数据属性和函数属性。

        可以通过__dict__访问属性的值,比如Student.__dict__[‘school’],但Python提供了专门的属性访问语法

    Student.school # 访问数据属性,等同于Student.__dict__['school']
    Student.choose # 访问函数属性,等同于Student.__dict__['choose']

        同理操作对象的属性也是一样的,除了查看属性外我们还可以修改属性

    stu1_obj=Student('egon',18,'male')
    print(stu1_obj.__dict__)
    
    print(stu1_obj.stu_name)#查看属性
    stu1_obj.course='python' #添加属性
    stu1_obj.stu_age = 20 #修改属性
    del stu1_obj.stu_gender #删除属性
    print(stu1_obj.__dict__)

         属性的访问顺序和查找方法:

        对象的名称空间里只存放着对象独有的属性,而对象们相似的属性是存放于类中的。对象在访问属性时,会优先从对象本身的__dict__中查找,未找到,则去类的__dict__中查找

        

        1、类的数据属性是共享给所有对象用的,大家访问的地址都一样

    print(id(Student.school))# 2493299721864
    print(id(stu1_obj.school))# 2493299721864
    print(id(stu2_obj.school))# 2493299721864

        因此当类中的变量的值改变时对象中的也会跟着改变

    Student.school='OLDBOY'
    print(stu1_obj.school)#OLDBOY

        2、类中定义的函数主要是给对象使用的,而且是绑定给对象的,虽然所有对象指向的都是相同的功能,但是绑定到不同的对象就是不同的绑定方法,内存地址各不相同

    print(id(Student.choose)) # 4335426280
    
    print(id(stu1_obj.choose)) # 4300433608
    print(id(stu2_obj.choose)) # 4300433608

        类调用自己的函数属性必须严格按照函数的用法来

    Student.tell_stu_info(stu1_obj)
    Student.tell_stu_info(stu2_obj)

        绑定方法的特殊之处在于:谁来调用绑定方法就会将谁当做第一个参数自动传入

    stu1_obj.tell_stu_info() #Student.tell_stu_info(stu1_obj)
    stu2_obj.tell_stu_info() #Student.tell_stu_info(stu2_obj)

        强调一点:因为python底层代码规定,在类中定义函数时必须要在括号内定义一个变量来接收传入的对象

    四 总结

      Python中一切皆为对象,且Python3中类与类型是一个概念,因而绑定方法我们早就接触过

    #类型list就是类
    >>> list
    <class 'list'>
    
    #实例化的到3个对象l1,l2,l3
    >>> l1=list([1,2,3])
    >>> l2=list(['a','b','c'])
    >>> l3=list(['x','y'])
    
    #三个对象都有绑定方法append,是相同的功能,但内存地址不同
    >>> l1.append
    <built-in method append of list object at 0x10b482b48>
    >>> l2.append
    <built-in method append of list object at 0x10b482b88>
    >>> l3.append
    <built-in method append of list object at 0x10b482bc8>
    
    #操作绑定方法l1.append(4),就是在往l1添加4,绝对不会将4添加到l2或l3
    >>> l1.append(4) #等同于list.append(l1,4)
    >>> l1
    [1,2,3,4]
    >>> l2
    ['a','b','c']
    >>> l3
    ['x','y']

      在上述介绍类与对象的使用过程中,我们更多的是站在底层原理的角度去介绍类与对象之间的关联关系,如果只是站在使用的角度,我们无需考虑语法“对象.属性"中”属性“到底源自于哪里,只需要知道是通过对象获取到的就可以了,所以说,对象是一个高度整合的产物,有了对象,我们只需要使用”对象.xxx“的语法就可以得到跟这个对象相关的所有数据与功能,十分方便且解耦合程度极高。

  • 相关阅读:
    利用Node.js的Net模块实现一个命令行多人聊天室
    JS判断鼠标进入容器方向的方法和分析window.open新窗口被拦截的问题
    Node.js:进程、子进程与cluster多核处理模块
    Node.js:理解stream
    Node.js:Buffer浅谈
    Node.js:OS模块
    一个unsigned int 数的二进制表示中有多少个1
    一个栈的入栈序列为ABCDEF,则不可能的出栈序列是
    文件操作:获取一个文件行数的方法
    利用sourceinsight宏(Quicker.em)提高编码效率和质量
  • 原文地址:https://www.cnblogs.com/bk134/p/12652223.html
Copyright © 2011-2022 走看看