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
  • 相关阅读:
    经纬度转十进制 、十进制转经纬度 、没有秒
    PowerDesigner使用
    Kafka日志存储原理
    ambari rest api (三)
    ambari rest api (修改集群配置文件)
    使用QJM构建HDFS HA架构(2.2+)
    Hadoop NameNode 高可用 (High Availability) 实现解析
    hadoop2.x Federation
    hdfs HA原理
    使用JSONObject生成和解析json
  • 原文地址:https://www.cnblogs.com/fjfsu/p/15424856.html
Copyright © 2011-2022 走看看