zoukankan      html  css  js  c++  java
  • 类与对象

    类与对象

    类:

    是一组相关属性和行为的集合。可以看成是一类事物的模板,使用事物的属性特征和行为特征来描述该 类事物。

    举例:猫。

    属性:名字、体重、年龄、颜色。   行为:走、跑、叫。

    对象:

    类的具体体现,实现。

    举例:一只小猫。

    属性:tom、5kg、2 years、yellow。   行为:溜墙根走、蹦跶的跑、喵喵叫。

    类与对象的关系

    • 是对一类事物的描述,是抽象的。
    • 对象是一类事物的实例,是具体的。
    • 对象的模板,对象的实体。
    • 对象是根据来创建的,中有什么对象就有什么

    举例:当我们提到手机的时候,我们就能想到手机它能够,打电话、听电话、看视频、看图片、听音乐、发信息等基础功能。

          但是,我们并不能知道这个手机是什么颜色、品牌、价格等具体实物,这就是类

          使用红色的5000元的华为手机,打着电话,那这个手机就是一个对象。

    Python中一切皆对象。

    1.类的创建

    • 创建语法
      • #类的创建
        '''
        注意:类名的首字母需要大写,类名也可使用多个单词组成,但是,每个单词的首字母都要大写
        请遵循这个规范
        '''
        class Student:  #使用class关键字创建了Student这个类
            pass
        
        #Python中一切皆对象,那么这个Student是对象吗?内存有开辟空间吗?
        print(id(Student))      #查看是否开辟空间及其内存地址 1872433931728
        print(type(Student))    #查看Student的数据类型    <class 'type'>
        print(Student)          #查看Student的值   <class '__main__.Student'>
    • 类的组成
      • 类属性:类中方法外的变量称为类属性,被该类的所有对象共享
      • 实例属性:定义在类的方法中的属性  
      • 实例方法
      • 静态方法:使用类名直接访问  
      • 类方法:使用类名直接访问
        • class Student:
              native_pace  = "中国"          #在类里面定义的变量,称为类属性
          
              #初始化方法__init__(self):    当创建对象时,系统会自动调用该方法,从而实现对对象进行初始化  注意:__new__才是构造方法(为对象开辟空间)
              def __init__(self,name,age):
                  self.name = name         #实例属性
                  self.age = age             #实例属性
          
              #实例方法   在类之外定义的叫做函数,在类里面定义的叫做方法
              def eat(self):      #实例方法必须传递一个形参self,可其他名字
                  print("学生在吃饭")
          
              # 使用staticmethod关键字定义静态方法
              @staticmethod
              def fun():          #静态方法不传递任何参数
                  print("使用了staticmethod进行修饰,所以我是静态方法")
          
              #使用classmethod关键字定义类方法
              @classmethod
              def cm(cls):       #类方法必须传递一个形参cls(即class),可其他名字
                  print("使用了classmethod进行修饰,所以我是类方法")

    2.对象的创建

    • 创建类和对象
    class Student:
        native_pace  = "中国"          #在类里面定义的变量,称为类属性
    
        #初始化__init__(self):    当创建对象时,系统会自动调用该方法,从而实现对对象进行初始化
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
        #实例方法   在类之外定义的叫做函数,在类里面定义的叫做方法
        def eat(self):      #实例方法必须传递一个形参self,可其他名字
            print("学生在吃饭")
    
        # 使用staticmethod关键字定义静态方法
        @staticmethod
        def fun():          #静态方法不传递任何参数
            print("使用了staticmethod进行修饰,所以我是静态方法")
    
        #使用classmethod关键字定义类方法
        @classmethod
        def cm(cls):       #类方法必须传递一个形参cls,可其他名字
            print("使用了classmethod进行修饰,所以我是类方法")
    
    student_1 = Student("张三",20)
    print(id(student_1))      #查看student_1实例对象的空间地址     1229230570848(10进制)--->0x0000011E33D9FD60(16进制)
    print(type(student_1))    #查看student_1的数据类型        <class '__main__.Student'>
    print(student_1)          #查看student_1实例对象的值      0x0000011E33D9FD60 可以看出实际输出的是内存地址
    • 对象使用类的属性和方法
      • student_1 = Student("张三",18)
        print(student_1.age)            #18
        print(student_1.name)           #张三
        print(student_1.native_pace)    #中国  (这个是类属性)
        student_1.fun()                 #使用了staticmethod进行修饰,所以我是静态方法
        student_1.eat()                 #张三 学生在吃饭
        student_1.cm()                  #使用了classmethod进行修饰,所以我是类方法
        #使用类名调用方法
        Student.eat(student_1)          #张三 学生在吃饭
        #类方法的使用方法
        Student.cm()
        #静态方法的使用方法
        Student.fun()
    • self参数:
      • 类的所有方法都必须至少有一个名为self的参数,并且必须是方法的第一个参数。
      • 如果把类比作制造汽车的图纸,那么由实例化的对象才是正真可以开的汽车。根据一张图纸可以设计出千千万万的汽车,他们长得都差不多,但是它们都有不同的属性,如颜色不同、内饰不同、所以self就相当于每辆车的编号,有了self,就可以轻轻松松找到对应的车了。
      • 在Python中,由同一个类可以生成无数个对象,当一个对象的方法被调用时,对象会将自身的引用作为第一个参数传递给该方法,那么Python就知道需要操作哪个对象的方法了。

    3.动态绑定属性和方法

    • 虽然简单粗暴,但是在实际开发中不推荐使用
      • 如果在程序运行时,没有找到属性,那么程序会报错
    • 这些属性应该在定义类时就封装在类的内部,而不是在类的外部进行添加
    #为对象stu_1动态绑定属性gender
    stu_1.gender = ""
    print(stu_1.gender)
    #print(stu_2.gender)    #报错,因为实例化对象stu_2并没有属性gender
    
    #为对象stu_1动态绑定函数,注意:show函数要提前定义好,否则在赋值时,会抛出异常
    def show():
        print("这是一个被",stu_1,"绑定的show函数")
    stu_1.show = show
    stu_1.show()
    #stu_2.show()   #此处代码报错,因为对象str_2并没有绑定show函数

     4.初始化方法

    • 当使用  类名()  创建对象时,会自动执行以下操作:
      • 为对象在内存中分配空间     ——创建对象
      • 为对象的属性设置初始值          ——初始化方法(  __init__ )
    • 这个初始化方法就是__init__方法,是对象的内置方法
      • init方法是用来定义一个类具有哪些属性的方法!
      • 在实例化对象时,会自动调用init方法
    • #没有写调用函数的代码,但是init中的代码在实例化时被调用了。
      class Cat:
          def __init__(self):
              print("该方法在实例化对象时,会被调用")
              
      Tom = Cat()     #该方法在实例化对象时,会被调用
    • 在初始化方法内部定义属性
      • 在__init__方法内部使用 self.属性名 = 属性初始值 就可以 定义属性
      • 定义属性之后,在实例化对象时,对象都会具备该属性
      • class Cat:
            def __init__(self):
                print("该方法在实例化对象时,会被调用")
                self.name = "Tom"
        
        Tom = Cat()     #该方法在实例化对象时,会被调用
        print(Tom.name) #Tom
    •  改造初始化方法——初始化的同时设置初始值
      • 在开发中,如果希望在 创建对象的同时,就设置对象的初始属性,可以对__init__方法进行改造
      1. 把需要用的到属性值,定义成__init__属性
      2. 在方法内部使用 self.属性名 = 形参 接受对象传递过来的参数
      • class Cat:
            def __init__(self,name):
                self.name = name
        
            def eat(self):
                print(self.name,"在吃东西")
        
        Tom = Cat("Tom")
        bl = Cat("小黑")
        Tom.eat()       #Tom 在吃东西
        bl.eat()        #小黑 在吃东西
    • 对象的生命周期
      • 应用场景:
        • __init__改造初始化方法,让创建对象更加灵活
        • __del__对象在销毁前会自动被调用的一个方法,如果希望对象在销毁前,可以再做一些事情,可以考虑以下__del__方法
      • 生命周期
        • 一个对象从调用    类名()   创建,声明周期开始
        • 一个对象__del__方法一旦被调用,声明周期结束
      • class Cat:
            def __init__(self,name):
                self.name = name
        
            def eat(self):
                print(self.name,"在吃东西")
        
            def __del__(self):
                print("我无了")
        
        Tom = Cat("Tom")
        Tom.eat()       #Tom 在吃东西
        print("*"*25)
        #运行结果
        Tom 在吃东西
        *************************
        我无了

        如果使用del在分割线前摧毁对象,看下执行效果

        Tom = Cat("Tom")
        Tom.eat()       
        del Tom
        print("*"*25)
        #运行结果
        Tom 在吃东西
        我无了
        *************************

        由此可以看出当对象销毁时,对自动调用__del__方法

    5.详解

    5.1术语 --实例

    1. 使用面向对象开发,第1步是设计类
    2. 使用类名()创建对象,创建对象的步骤有两步:
      • 在内存中为对象开辟空间
      • 调用初始化方法 __init__ 为对象初始化
    3. 对象创建后,内存中就有一个实实在在 的存在 ——实例
      • 注意:

      1. 每一个对象 都有自己独立的内存空间,保存各自     

      2. 多个对象的方法在内存中只有一份,在调用方法时,需要把对象引用 传递到方法内部

        实例化对象时,实例属性会被分配好空间,但是方法不会,方法会在对象调用方法时(即实例方法时),将对象的地址传递给类的这个方法,
        告诉类的这个方法是该对象在调用在调用这个方法(因此对象的实例方法是保存在类所在的内存空间)

    5.2类是以个特殊的对象

    • Python中一切皆对象:
      • class AAA  定义的类,属于类对象
      • obj1 = AAA() 属于 实例对象
    • 在程序运行时,类同样会被加载到内存
    • 在Python中,类是一个特殊的对象——类对象
    • 在程序运行时,类对象在内存中只有一份,使用一个类可以创建出很多个对象实例
    • 除了封装实例的属性和方法外,类对象也可以拥有自己的属性和方法:
      1. 类属性
      2. 类方法
    • 通过 类名. 的方式可以访问类的属性或者调用类的方法

    5.3类属性和实例属性

    1. 概念和使用
      • 类属性 就是给类 定义的属性
      • 通常用来记录 与这个类相关的特征
      • 类属性不会用来记录具体对象的特征
    2. 示例需求
      • 定义一个工具类
      • 每个工具都由自己的name
      • 需求——知道 使用这个工具类创建了多少个工具对象
      •  1 #类属性演示
         2 class Tool(object):
         3     #使用赋值语句定义类属性count,用来记录创建工具对象的总数
         4     count = 0
         5     def __init__(self,name):
         6         self.name = name
         7         #针对类属性做一个计数+1
         8         Tool.count += 1
         9 
        10 #创建工具对象
        11 tool_1 = Tool("斧子")
        12 tool_2 = Tool("榔头")
        13 tool_3 = Tool("铁锤")
        14 print(tool_3.count)     #3
        15 print(Tool.count)       #3
        16 
        17 #动态绑定属性赋值
        18 tool_3.count = 6
        19 '''
        20 调用对象的属性和方法时,搜索属性和方法的方式为
        21 先搜索对象的属性和方法,如果没有找到然后
        22 再搜索类的属性和方法。
        23 '''
        24 print(tool_3.count)
        25 """
        26 运行结果:6  
        27 如果动态绑定属性并赋值,那么只是在对象的内存空间存在该属性及其值,
        28 搜索时会先搜索对象的内存空间,在去搜索类的内存空间,
        29 tool_3进行了动态绑定属性 count = 6 ,
        30 那么对象 tool_3 的空间就有该属性和值
        31 """
        32 print(Tool.count)       #3
        统计实例化对象个数
    3. 属性的获取机制
      • Python中的属性存在一个向上查找的机制
      • 因此要访问属性的两种方式:
        • 类名.类属性
        • 对象.类属性   (不推荐)
      • 如果使用 对象.属性 = 值 赋值语句,只会给对象添加一个属性,而不会影响到类属性的值
      • 代码演示:查看5.3“统计实例化对象个数”

     

    5.4类方法

    • 类属性 就是针对 类对象 定义的值
      • 使用赋值语句在class关键字下方可以定义类属性
      • 类属性用于记录与这个类相关的特征
    • 类方法就时针对类对象定义的方法
      • 在类方法内部可以直接访问类属性或者直接调用其他的类方法
    • 语法格式:
      • @classmethod
        def   类方法名(cls):
                pass
    • 类方法需要用 修饰器  @classmethod 来标识,告诉解释器这是一个类方法
    • 类方法第一个参数 应该是 cls 
      • 由哪一个类调用的类方法,方法内的cls就是哪一个类的引用
      • 这个参数和实例方法的第一个参数 self 类似
      • 提示:使用其他名称也可以,不过习惯使用cls
    • 方法内部
      • 可以通过cls.访问类属性
      • 也可以通过cls.调用其他类方法
    • 代码演示
      •  1 #类方法
         2 class Tool(object):
         3     count = 0
         4     def __init__(self,name):
         5         self.name = name
         6         Tool.count += 1
         7 
         8     @classmethod
         9     def show_tool(cls):
        10         print("对象工具的总数:",cls.count)
        11 
        12 t_1 = Tool("剪刀")
        13 t_2 = Tool("榔头")
        14 Tool.show_tool()    #对象工具的总数: 2
        15 t_1.show_tool()     #对象工具的总数: 2
        类方法

    5.5静态方法

    • 在开发时,如果需要在类中封装一个方法,这个方法
      • 既 不需要 访问 实例属性 或者调用 实例方法
      • 也 不需要 访问 类属性 或这调用 类方法
    • 这个时候,可以把这个方法封装成一个静态方法
    • 语法:
      • @staticmethod
        def 静态方法名():
                pass
    • 静态方法需要用 修饰器 @staticmethod 来标识,告诉解释器这是一个静态方法
    • 通过 类名.  调用 静态方法
    • class Dog(object):
          count = 0
          @staticmethod
          def run():
              print("一只狗在跑")
      Dog.run()

    案例:

     1 #类和对象的练习
     2 class Game(object):
     3     top_score = 0
     4     def __init__(self,player_name):
     5         self.player_name = player_name
     6 
     7     @staticmethod
     8     def show_help():
     9         print("帮助信息:让僵尸打开大门")
    10 
    11     @classmethod
    12     def show_top_score(cls):
    13         print("历史记录:%d" % cls.top_score)
    14 
    15     def start_game(self):
    16         print("%s开始游戏啦······" % self.player_name)
    17 
    18 #显示帮助信息
    19 Game.show_help()
    20 #显示历史记录
    21 Game.show_top_score()
    22 #创建游戏着
    23 xm = Game("小明")
    24 #小明开始游戏
    25 xm.start_game()
    View Code
  • 相关阅读:
    聊聊WS-Federation
    用双十一的故事串起碎片的网络协议(上)
    责任链模式的使用-Netty ChannelPipeline和Mina IoFilterChain分析
    最小化局部边际的合并聚类算法(中篇)
    最小化局部边际的合并聚类算法(上篇)
    UVaLive 7371 Triangle (水题,判矩形)
    UVaLive 7372 Excellence (水题,贪心)
    POJ 3312 Mahershalalhashbaz, Nebuchadnezzar, and Billy Bob Benjamin Go to the Regionals (水题,贪心)
    UVa 1252 Twenty Questions (状压DP+记忆化搜索)
    UVa 10817 Headmaster's Headache (状压DP+记忆化搜索)
  • 原文地址:https://www.cnblogs.com/fjfsu/p/15424856.html
Copyright © 2011-2022 走看看