zoukankan      html  css  js  c++  java
  • 面向对象基础

    面向对象编程介绍

    面向过程编程

    面向过程编程的核心就是过程,过程指的是解决问题的步骤,也就是按照固定的顺序进行,执行程序,就好比流水线一样

    • 优点:复杂的问题简单化,流程化
    • 缺点:扩展性差

    面向对象编程

    面向对象编程的核心就是对象二字,对象就是特征与技能的结合体

    基于面向对象编程的思想编程,就好比在创造一个世界,你是这个世界的主人,想怎么写就怎么写

    • 优点:可扩展性强
    • 缺点:编程复杂度远远提高

    类与对象

    • 类就是种类,分类,类别

    对象就是特征与技能的结合体,我们可能有身高,体重,每个人的身高体重各不相同,但是都是有相似的特征的,就可以说我们是一类,而你和选课系统又不一样,因此

    类就是:一系列对象相似的特征与技能的结合体

    在现实生活中,我们先有的对象,然后才慢慢有了分类的概念

    现实生活中定义类和对象

    定义对象

    就按我们的选课系统来讲,首先我们得先有学生对象:

    • 对象一:

      • 特征:

        • 学校='oldboy'
        • 姓名='hades'
        • 年龄=18
        • 性别='男'
      • 技能:

        • 选课
    • 对象二:

      • 特征:

        • 学校='oldboy'
        • 姓名='bonnie'
        • 年龄=16
        • 性别='女'
      • 技能:

        • 选课

    定义类

    • 学生类
      • 相似的特征:
        • 学校='oldboy'
      • 相似的技能:
        • 选课

    程序中定义类和对象

    定义类

    语法:class 类名(类名需要使用驼峰体)

    class OldBoyStudent:
        school = 'oldboy'
        
        def course(self):
            print('is choosing course')
    
    • 定义函数时,函数只检测语法,不执行代码
    • 定义类时,类的代码会在类定义阶段就立刻执行,并会产生一个类的名称空间。
    print(OldBoyStudent.__dict__)
    
    {'__module__': '__main__', 'school': 'oldboy', 'course': <function OldBoyStudent.course at 0x00000207C4524D08>, '__dict__': <attribute '__dict__' of 'OldBoyStudent' objects>, '__weakref__': <attribute '__weakref__' of 'OldBoyStudent' objects>, '__doc__': None}
    

    __dict__就是这个类里面的元素静态函数、类函数、普通函数、全局变量以及一些内置的属性都是放在类__dict__里的

    print(OldBoyStudent.__dict__['school'])
    
    print(OldBoyStudent.school)
    
    oldboy
    oldboy
    
    OldBoyStudent.course(123)
    
    is choosing course
    
    OldBoyStudent.country = 'china'   # 把country这个元素也放到OldBoyStudent这个类里面去了
    
    print(OldBoyStudent.country)
    
    print(OldBoyStudent.__dict__)
    
    china
    {'__module__': '__main__', 'school': 'oldboy', 'course': <function OldBoyStudent.course at 0x00000207C4524D08>, '__dict__': <attribute '__dict__' of 'OldBoyStudent' objects>, '__weakref__': <attribute '__weakref__' of 'OldBoyStudent' objects>, '__doc__': None, 'country': 'china'}
    

    定义对象

    • 调用类就会产生对象,调用类的过程又称为类的实例化,实例化的结果称为类的对象/实例

    调用类就会有一个返回值,该返回值就是类的一个具体的对象

    stu1 = OldBoyStudent()
    print(stu1.school)
    print(stu1.country)
    
    oldboy
    china
    
    stu2 = OldBoyStudent()
    stu2.name = 'hades'
    print(stu2.school)
    print(stu2.country)
    print(stu2.name)
    print(stu1.name)   # 报错,stu1这个对象根本就没有name这个变量名
    
    
    oldboy
    china
    hades
    
    
    
    ---------------------------------------------------------------------------
    
    AttributeError                            Traceback (most recent call last)
    
    <ipython-input-13-c770dcc4850e> in <module>
          4 print(stu2.country)
          5 print(stu2.name)
    ----> 6 print(stu1.name)   # 报错,stu1这个对象根本就没有name这个变量名
    
    
    AttributeError: 'OldBoyStudent' object has no attribute 'name'
    

    如此可以证明每一个对象之间是相互独立的,互不干扰,但如果类的属性发生变化,所有的对象也会发生变化,就如上面OldBoystudent.country = 'china',所有的类的对象都具备了这个属性

    定制对象的独有特征

    定制对象独有属性

    class Student:
        school = 'oldboy'
        
        def choose_course(self):
            print('is choosing course')
            
    stu1 = Student()
    stu2 = Student()
    stu3 = Student()
    
    print(stu1.__dict__)
    print(stu2.__dict__)
    
    {}
    {}
    
    • 对于类的对象,本身和类类似,也是一个名称空间,但是对象的名称空间用来存放对象独有的属性,而类中存放的是对象们共有的名字。因此我们可以直接为对象单独赋予属性而不会影响其他对象
    stu1.name = 'hades'
    stu1.age = 27
    stu1.weigth = 120
    print(stu1.__dict__)
    print(stu2.__dict__)
    
    {'name': 'hades', 'age': 27, 'weigth': 120}
    {}
    
    stu2.name = 'bonnie'
    stu2.age = 16
    stu2.weight = 90
    print(stu2.__dict__)
    
    {'name': 'bonnie', 'age': 16, 'weight': 90}
    

    类定义阶段定制属性

    class Student:
        school = 'oldboy'
        
        def __init__(self,name,age,weight):
            """类在实例化的时候自动触发"""
            self.name = name
            self.age = age
            self.weight = weight
        
        def choose_course(self):
            print(f'{self.name}is choosing course')
            
    try:       
        stu1 = Student() 
    except Exception as e:
        print(e)
    
    __init__() missing 3 required positional arguments: 'name', 'age', and 'weight'
    
    stu1 = Student('hades',27,120)
    print(stu1.__dict__)
    
    {'name': 'hades', 'age': 27, 'weight': 120}
    
    • 通过上述现象可以发现,调用类时发生两件事:
      • 创造一个空对象
      • 自动触发类中__init__功能的执行,将stu1以及调用类括号内的参数一同传入

    对象的属性查找顺序

    属性查找

    • 函数的查找顺序为:就近原则,从当前位置向外进行查找,如果当前位置为局部名称空间,则是局部—-》全局——》内置

    • 类的查找顺序为:先从自己的名称空间进行查找,如果找不到,就去类的名称空间进行查找,如果还是找不到就会报错

    class Student:
        school = 'oldboy'
        count = 0
        
        def __init__(self,name,age,weight):
            self.name = name
            self.age = age
            self.weight = weight
            Student.count += 1
        
        def choose_course(self):
            print(f'{self.name}is choosing course')
            
            
    stu1 = Student('hades',27,120)
    print(stu1.count)
    stu2 = Student('bonnie',16,90)
    print(stu1.count)
    print(stu2.count)
    stu3 = Student('zhu',2,150)
    
    print(Student.count)
    
    1
    2
    2
    3
    
    print(stu1.__dict__)
    print(stu2.__dict__)
    print(stu3.__dict__)
    
    {'name': 'hades', 'age': 27, 'weight': 120}
    {'name': 'bonnie', 'age': 16, 'weight': 90}
    {'name': 'zhu', 'age': 2, 'weight': 150}
    
    • 由于上述修改的是类的属性,所以所有对象属性都会进行修改

    类与对象的绑定方法

    类与对象的绑定方法

    class Student:
        school = 'oldboy'
        
        def __init__(self,name,age,weight):
            self.name = name
            self.age = age
            self.weight = weight
        
        def choose_course(self):
            print(f'{self.name} is choosing course')
            
            
        def func(self):
            print('from func')
            
    
    • 类的名称空间中定义的属性和函数都是这个类的对象共有的,所有的对象都会有这些属性

    • 对象的名称空间中的属性只是这个对象独有的,属于这个对象私有物品,是不会和其他对象进行分享的

    类的绑定对象

    stu1 = Student('hades',27,120)
    stu2 = Student('bonnie',16,90)
    stu3 = Student('zhu',2,150)
    
    print(stu1.name)
    stu1.choose_course()
    print(stu2.age)
    print(stu3.weight)
    
    hades
    hades is choosing course
    16
    150
    
    • 类中定义的函数就是一个普通的函数,所以我们定义的时候有几个形参我们调用的时候就要传几个实参

    对象的绑定方法

    • 类中定义的函数是共享给所有对象的,对象也可以使用,而且是绑定给对象用的

    • 绑定的效果:绑定给谁,就应该由谁来调用,谁来调用就会将谁当作第一个参数自动传入

    print(id(stu1.choose_course))
    print(id(stu2.choose_course))
    print(id(stu3.choose_course))
    print(id(Student.choose_course))   # 不相同
    
    2232380939208
    2232380939208
    2232380939208
    2232383095672
    
    • 补充:类中定义的函数,类确实可以使用,但其实类定义的函数大多情况下都是绑定给对象用的,所以在类中定义的函数都应该自带一个参数self
    stu1.choose_course()
    stu2.choose_course()
    stu3.choose_course()
    
    hades is choosing course
    bonnie is choosing course
    zhu is choosing course
    

    类与数据类型

    类与数据类型

    • python3中统一了类与类型的概念,类就是类型
    class Foo:
        pass
    
    obj = Foo()
    
    lis1 = [1,2,3]
    lis2 = list([4,5,6])
    
    print(type(obj))
    
    print(lis1)
    print(lis2)
    print(type(lis))
    
    <class '__main__.Foo'>
    [1, 2, 3]
    [4, 5, 6]
    <class 'list'>
    
    • lis1和lis2都是list类实例化的对象,因此lis2使用append方法与lis1无关
    lis2.append(7)
    print(lis1)
    print(lis2)
    
    [1, 2, 3]
    [4, 5, 6, 7]
    

    list.append()方法原理

    class Student:
        school = 'oldboy'
        
        def __init__(self,name,age,weight):
            self.name = name
            self.age = age
            self.weight = weight
        
        def choose_course(self):
            print(f'{self.name} is choosing course')
            
            
        def func(self):
            print('from func')
            
    stu1 = Student('hades',27,120)
    
    stu1.choose_course()
    
    hades is choosing course
    
    Student.choose_course(stu1)
    
    hades is choosing course
    
    lis = [1,2,3]
    lis.append(4)
    print(lis)
    list.append(lis,5)
    print(lis)
    
    [1, 2, 3, 4]
    [1, 2, 3, 4, 5]
    

    对象的高度整合

    对象和函数一样,可以引用、作为返回值、作为参数、作为容器元素

    在类里面封装了一大堆特征/数据,然后又封装了一大堆方法(方法用来专门用来操控这些数据的),并且在这基础上对于不同对象,这些属性和方法有不一样

  • 相关阅读:
    python3.x 基础五:模块
    python3.x 基础四:目录获取及目录规范
    python3.x 基础四:json与pickple
    python3.x 基础四:生成器与迭代器
    python3.x 基础三:装饰器
    python3.x 基础三:函数
    [leetcode]Anagrams
    [leetcode]Text Justification
    [leetcode]Single Number
    [leetcode]Longest Palindromic Substring
  • 原文地址:https://www.cnblogs.com/Hades123/p/11060668.html
Copyright © 2011-2022 走看看