代码之家  ›  专栏  ›  技术社区  ›  TCCV

对象与实例的区别

oop
  •  71
  • TCCV  · 技术社区  · 14 年前

    我知道这类问题 asked before 但是我仍然觉得这个答案太模糊了,我(而且,通过扩展,一些/大多数初学者)无法理解。

    我一直在尝试教自己编程的更广泛概念,而不是程序化的和基本的OOP。我了解OOP的具体概念(您创建了一个具有数据(成员)和函数(方法)的类,然后在运行时实例化该类,以实际完成这类工作)。

    我想我能理解什么是课堂( 类似于在编译时创建的实例的设计蓝图 )但如果是这样的话,物体是什么?我也知道,在基于原型的语言中,这会把事情搞得更糟,但也许这就是为什么在我的头脑中需要对对象和实例有一个清晰的区分。

    除此之外,我还与“对象”和“实例”的概念作斗争。我读到的很多资源(包括SO的答案)都说它们在很大程度上是相同的,区别在于语义。其他人说这两者之间有真正的概念上的区别。

    这里的专家能帮助初学者在OOP的世界里获得前进的“啊哈”时刻吗?

    再次感谢。

    注意:这不是家庭作业,我不上学-但是,我认为它可以帮助那些寻求家庭作业帮助的人。

    18 回复  |  直到 5 年前
        1
  •  119
  •   joe snyder    14 年前

    房屋设计的蓝图就像一个类描述。所有根据这幅蓝图建造的房子都是这一类的物品。给定的房子就是一个例子。

        2
  •  33
  •   Brian Mains    11 年前

    事实上,面向对象编程经常会造成混乱,在开发的哲学方面与计算机的实际机械工作之间产生一种脱节。我试着把这两个做个对比:

    OOP的基本概念是:类>>对象>>实例。

    类=蓝色打印。 这个物体是一个真实的东西,它是根据“蓝图”(比如房子)建造的。 实例是对象的虚拟副本(但不是真实副本)。

    对“实例”的更技术性解释是它是“内存引用”或引用变量。这意味着“实例”是内存中的一个变量, 只有 其中包含一个对象的内存地址。它所寻址的对象与该实例被称为“实例”的对象相同。如果你有一个对象的很多实例,那么你的内存中有很多不同的变量,它们都有相同的精确内存地址——它们都是同一个精确对象的地址。您不能“更改”实例,尽管在您的代码中看起来是这样。当您“更改”实例时,真正要做的是直接更改原始对象。在电子方面,处理器在改变原始对象的数据之前,会在内存中多放一个位置(引用变量/实例)。

    过程是:处理器>>实例的内存位置>>原始对象的内存位置。

    请注意,使用哪个实例并不重要-最终结果总是相同的。所有实例将继续在其内存位置(对象的内存地址)中维护相同的准确信息,只有对象会更改。

    类和对象之间的关系有点混乱,尽管从哲学上讲,这是最容易理解的(Blue print>>house)。如果对象是保存在内存某处的实际数据,那么“class”是什么?事实证明,从机械上讲,对象是类的精确副本。所以类只是内存中其他地方的另一个变量,它保存着与对象相同的准确信息。注意关系之间的区别:

    对象是 复制 班里的 实例是一个保存对象内存地址的变量。

    您还可以拥有同一类的多个对象,然后每个对象的多个实例。在这些情况下,每个对象的实例集的值是相等的,但对象之间的实例不是。例如:

    让A级 来自类A的let object1、object2和object3。

    //对象1与对象2和对象3具有相同的精确值,但在内存中的位置不同。

    来自对象1>>让obj1_instance1、obj1_instance2、obj1_instance3

    //所有这些实例的值和内存中的不同位置也相同。它们的值=object1.memoryAddress。

    等。

    当你开始介绍类型的时候事情会变得更混乱。下面是一个使用c中类型的示例:

    //假设类人存在 person john=new person();

    实际上,如果将此代码分解为两部分,则更容易分析它:

    Person john;
    john = new Person();
    

    在技术语言中,第一行“声明了 类型 人。但这意味着什么?一般的解释是我现在有一个空变量,它只能容纳一个人对象。但是等一下-它是一个空变量!变量内存位置中没有任何内容。事实证明,“类型”在机械上毫无意义。类型最初是作为一种管理数据的方法而发明的,而不是其他任何方法。即使在声明诸如int、str、chr等原语类型(不初始化它)时,计算机内也不会发生任何事情。编程的这种奇怪的语法方面是人们认为类是对象蓝图的一部分。OOP已经变得更容易与带有委托类型、事件处理程序等的类型混淆。我尽量不要过于关注它们,只需记住它们都是用词不当的。在变量成为对象或设置为对象的内存地址之前,变量不会发生任何变化。

    第二行也有点混乱,因为它同时执行两个操作:

    首先对右侧的“new person()”进行评估。它创建了一个新的Person类副本——也就是说,它创建了一个新的对象。

    左边的“john=”,然后进行评估。它将john转换为一个引用变量,给出了刚才在同一行右侧创建的对象的内存地址。

    如果你想成为一个优秀的开发人员,重要的是要理解没有一个计算机环境是基于哲学理想工作的。计算机甚至不是那么合乎逻辑——它们实际上只是一大组用基本布尔电路(主要是NAND和OR)粘合在一起的电线。

        3
  •  22
  •   Pushkarraj Pujari    7 年前

    单词 等级 来自 分类 ( 类别 放东西的地方 )现在我们都听说了 等级 就像一张蓝图,但这到底意味着什么?这意味着 等级 保存特定类别的描述,( 我想用Java来演示类、对象和实例之间的区别,我会要求读者在阅读时把它想象成一个故事,如果你不熟悉Java,那就无关紧要了。 )所以让我们从 类别 打电话 人的存在 因此,Java程序将表示如下

    class HumanBeing{ 
       /*We will slowly build this category*/ 
    }
    

    现在,什么属性可以 人的存在 一般拥有 名字 , 年龄 , 高度 , 重量 现在,让我们将自己限制在这四个属性中,让我们将其添加到我们的类别中。

    class HumanBeing{
        private String Name;
        private int Age;
        private float Height;
        private float Weight; 
    
       /*We still need to add methods*/
    
    }
    

    现在每个类别都有一个行为,例如类别 有吠叫、取物、打滚等行为。,同样,我们的类别 人的存在 也可以有一定的行为,例如当我们要求 人的存在 你叫什么名字/年龄/体重/身高?它应该给出它的名字/年龄/重量/高度,所以在Java中我们这样做如下

    class HumanBeing{
        private String Name;
        private int Age;
        private float Height;
        private float Weight;  
    
        public HumanBeing(String Name,int Age,float Height,float Weight){
           this.Name = Name;
           this.Age  = Age;
           this.Height = Height;
           this.Weight = Weight;
        }
    
        public String getName(){
          return this.Name;
        }
    
        public int getAge(){
          return this.age;
        }
    
        public float getHeight(){
          return this.Height;
        }
    
        public float getWeight(){
          return this.Weight;
        }
    }
    

    现在我们已经将行为添加到我们的类别中了 人的存在 ,所以我们可以问它的名字、年龄、身高、体重,但是你会问谁这些细节,因为 class HumanBeing 只是一个类别,它是一个蓝图,例如一个建筑师在他想要建造的建筑的纸上画了一个蓝图,现在我们不能再活在蓝图中了。( 它对建筑物的描述 )我们只有在大楼建成后才能住在里面 因此,我们需要从上面描述的类别中创建一个人类,那么我们如何在Java中做到这一点呢?

    class Birth{
      public static void main(String [] args){
        HumanBeing firstHuman = new HumanBeing("Adam",25,6.2,90);    
      }
    }
    

    现在在上面的例子中,我们已经创建了第一个名为年龄身高体重的人,那么在上面的代码中到底发生了什么?我们是 例示 我们的范畴 人的存在 即我们类的一个对象被创建

    注: 对象和实例不是同义词 在某些情况下,对象和实例似乎是同义词,但它们不是,我将给出这两种情况

    案例1:对象和实例似乎是同义词
    当我们说 HumanBeing firstHuman = new HumanBeing("Adam",25,6.2,90); 物体 我们的类别创建于 堆内存 并分配了一些地址, firstHuman 保留对该地址的引用,现在该对象是 人类的目标 而且 人类的例子 . 在这里,对象和实例似乎是同义词, 我要重复一遍他们不是同义词

    让我们重新开始我们的故事,我们创造了我们的第一个孩子,现在我们可以问他的名字,年龄,身高,体重,这就是我们在爪哇做的。

    class Birth{
      public static void main(String [] args){
        HumanBeing firstHuman = new HumanBeing("Adam",25,6.2,90);
        System.out.println(firstHuman.getName());
        System.out.println(firstHuman.getAge());
        ...
        ...  
      }
    }
    

    所以我们有了第一个人,让我们通过给第一个人一些资格来移动羽毛,让我们让他成为医生,所以我们需要一个叫做 医生 给我们的医生一些行为,所以在爪哇我们做如下

    class Doctor extends HumanBeing{
       public Doctor(String Name,int Age,float Height,float Weight){
          super(Name,Age,Height,Weight);
       }
       public void doOperation(){
        /* Do some Operation*/ 
       }
    
       public void doConsultation(){
        /* Do so Consultation*/
       }
    }  
    

    这里我们使用了 遗传 这在代码中带来了一些可重用性,每一个医生都将永远是一个人类第一,所以一个医生的名字、年龄、体重、身高将从人类继承而不是再写,请注意,我们刚刚写了一个医生的描述,我们还没有创建一个,所以让我们在我们的 class Birth

    class Birth{
      public static void main(String [] args){
        Doctor firstDoctor = new Doctor("Strange",40,6,80);
        .......
        .......
        /*Assume some method calls , use of behaviour*/
        .......
        .......    
      }
    }
    

    案例2:对象和实例不是同义词
    在上面的代码中,我们可以看到我们是 给我们的分类医生一个实例,让它复活 也就是说,我们只是在创造一个 类别医生的对象 ,我们已经知道了 对象是在堆内存上创建的 firstDoctor 在堆中保存对该对象的引用;

    这个特定的对象 第一博士 如下(请注意 第一博士 保存对对象的引用,而不是对象本身)

    1. 第一博士 一个对象 class Doctor 一个实例 班医
    2. 第一博士 不是的对象 人类阶级 但是 一个实例 人类阶级

    因此,一个特定的对象可以是一个特定类的实例,但它不必是该给定类的对象

    结论:

    如果一个对象满足某一特定类别的所有特征,它就被称为该特定类别的实例。

    现实世界的例子是这样的,我们首先作为人类出生,所以把我们想象成人类的对象,现在当我们长大后,我们承担起责任,学习新的技能,在生活中扮演不同的角色,例如儿子,兄弟,女儿,父亲,母亲,现在我们到底是什么?我们可以说,我们是人类的对象,但兄弟、女儿等的例子。

    我希望这有帮助

    谢谢您

        4
  •  12
  •   jww    9 年前

    对象是内存中的东西,而实例是引用它们的东西。上图中:

    • std(实例)->学生对象(右)
    • std1(实例)->学生对象(左)
    • std2(实例)->学生对象(左)
    • std3(实例)->无对象(空)

    对象是内存中的东西,而实例是引用它们的东西。上图中:

    • std(实例)->学生对象(右)
    • std1(实例)->学生对象(左)
    • std2(实例)->学生对象(左)
    • std3(实例)->无对象(空)
        5
  •  5
  •   sukru    14 年前

    对象是类的实例(对于基于类的语言)。

    我认为这是我能想到的最简单的解释。

        6
  •  5
  •   Derek Litz    14 年前

    类定义对象。在许多语言中,您甚至可以进一步说,接口定义了对象之间的公共属性和方法。

    物体是指 可以 代表现实世界中的某些东西。当您希望对象 事实上 表示现实世界中必须实例化的对象。实例化意味着您必须定义这个特定对象的特性(属性),通常通过一个构造函数。

    一旦定义了这些特征,现在就有了对象的实例。

    希望这能解决问题。

        7
  •  2
  •   miguel.negrao    9 年前

    “一个类描述了一组称为其实例的对象。”—Xerox Learning Research Group,“The Smalltalk-80 System”,Byte Magazine第06卷第08号,第39页,1981年。

        8
  •  1
  •   Simon    14 年前

    我认为重要的是指出,通常有两件事。蓝图和副本。人们倾向于命名这些不同的事物;类、对象、实例只是人们为它们使用的一些名称。重要的是有蓝图和它的副本——不管它们的名字是什么。如果你已经对这两件事有了理解,那就避免其他让你困惑的事情。

        9
  •  1
  •   Geosphere    9 年前

    我想最好的答案已经给出了。

    类是蓝图,对象是建筑物或蓝图的例子也为我带来了好处。

    有时,我想认为类是模板(就像在MS Word中一样),而对象是使用模板的文档。

        10
  •  1
  •   Teju MB    7 年前

    什么是物体?

    对象是类的实例。通过在你周围找到真实世界的例子,可以更好地理解对象。你的书桌,你的笔记本,你的汽车都是一个很好的现实世界的一个物体的例子。

    现实世界中的物体有两个特点,它们都有状态和行为。人类也是一个很好的例子,我们人类有状态/属性-名字,身高,体重和行为-行走,跑步,说话,睡觉,代码:P。

    什么是班级?

    类是描述对象详细信息的蓝图或模板。这些细节是

    名称 属性/状态 操作/方法

    class Car 
    {
        int speed = 0;
        int gear = 1;
    
        void changeGear(int newGear)
        {
            gear = newGear;
        }
    
        void speedUp(int increment) 
        {
            speed = speed + increment;
        }
    
        void applyBrakes(int decrement) 
        {
            speed = speed - decrement;
        }
    }
    

    考虑上面的例子,字段 speed gear 将表示对象的状态和方法 changeGear , speedUp applyBrakes 定义汽车对象与外部世界的行为。

    参考文献:

        11
  •  0
  •   Jack    14 年前

    让我们比较一下苹果。我们都知道什么是苹果。它是什么样子的。尝起来像什么。那是一门课。它是事物的定义。这是我们所知道的。

    现在去找一个苹果。这是一个实例。我们可以看到。我们可以尝尝。我们可以用它来做事情。这就是我们拥有的。

    class=我们所知道的。定义。

    对象/实例=符合该定义的东西,我们可以用它来做事情。

        12
  •  0
  •   supercat    14 年前

    在某些情况下,“对象”一词可用于描述实例,但在其他情况下,它用于描述 参考 一个实例。“实例”一词仅指实际实例。

    例如,一个列表可以描述为一个对象集合,但它实际包含的是对对象实例的引用。

        13
  •  0
  •   Jose Diaz    14 年前

    我一直喜欢一个概念,这个概念等同于一个类的定义。 "Abstract Data Type" . 也就是说,当您定义一个类时,您正在定义一种新类型的“某物”,用原语和其他“某物”表示它的数据类型,用函数和/或方法表示它的行为。(对一般性和形式主义感到抱歉)

    每当定义类时,都会打开一个新的 可能性 为了定义具有其属性和行为的某些实体,当您实例化和/或从中创建特定对象时,实际上 物化 这种可能性。

    有时,术语“对象”和“实例”可以互换。一些OOP纯粹主义者会坚持认为一切都是一个对象,我不会抱怨,但在现实的OOP世界中,我们开发人员使用两个概念:

    1. 类:抽象数据类型示例,从中可以派生其他ADT并创建对象。
    2. 对象:也称为实例,表示由给定抽象数据类型表示的数据结构和函数的特定示例。
        14
  •  0
  •   user1494736    12 年前

    面向对象编程是一种 system metaphor 这有助于你组织你的程序需要处理的知识,以使你更容易开发你的程序。当你选择使用oop编程时,你会拿起你的oop谷歌,然后你决定通过发送消息,你会看到现实世界中有多少对象在相互协作。你看到的不是一个开汽车的人,而是一个向汽车发送信息,表明他想让汽车做什么。这辆车是一个很大的物体,它会通过发送一个信息给它的发动机或轮子来响应这个信息,从而能够正确地响应司机在信息中告诉他的行为,等等……

    在你创建了系统隐喻,你将所有现实视为发送信息的对象之后,你决定把你看到的所有与你的问题域相关的东西都放在电脑中。在那里你注意到有很多人在驾驶不同的卡,而将它们中每一个的行为单独编程是没有意义的。伊利,因为他们的行为都是一样的…所以你可以说两件事:

    • 所有这些人的行为都一样,所以我将创建一个名为 司机将指定世界上所有司机的行为, 因为他们的行为都是一样的。(您使用的是基于类的OOP)
    • 或者你可以说嘿!第二个司机和第一个司机的行为一样,只是他喜欢开得快一点。第三个司机和第一个司机的行为一样,只是他喜欢在开车时曲折行驶。(您使用基于原型的OOP)。

    然后你开始把所有驱动程序的行为(或者第一个驱动程序的行为,以及第二个和第三个驱动程序与第一个驱动程序的不同)的信息输入计算机,在一段时间后,你有了你的程序,你用代码创建了三个驱动程序,这三个驱动程序是你在电脑中使用的模型,以重新引用你在现实中看到的驱动程序。世界。您在PC中创建的这3个驱动程序是原型(实际上第一个是原型,第一个可能是原型本身,这取决于您如何建模)或您创建的类的实例。 实例和对象之间的区别在于,对象是您在现实世界中使用的隐喻。你选择把这个人和汽车看作是对象(不应该说你把他们看作是实例),在他们之间协作。然后你用它作为灵感来创建你的代码。实例只存在于您的程序中,在您创建原型或类之后。“对象”存在于PC之外,因为它是您用来将现实世界与程序结合起来的映射。它将这个人与你在PC中创建的驱动程序实例结合在一起,所以对象和实例是非常相关的,但它们并不完全相同(一个实例是程序中一个对象的“腿”,另一个“腿”在现实世界中)。

        15
  •  0
  •   GeekSpecs    9 年前

    在这个线程中扩展前面给出的一个示例…

    考虑一个场景——有一个要求,为了居住目的,需要在一个街区内建造5栋房子。这5所房子都有一个共同的建筑结构。 建筑结构是 . 房子是 对象 . 每个有人住在里面的房子都是 实例 .

        16
  •  -2
  •   SrinivasReddy    11 年前

    对象:当我们创建一个对象时,该对象占用了一些内存。 示例:test t=new test();//这里t是test类的对象

    实例:当我们声明实例时,该实例不占用单独的内存 示例:test t;//这里t是test类的实例

        17
  •  -2
  •   shekhar kadam    10 年前

    简单地说,对象是唯一不分配内存的声明。 实例是一个分配内存的类的对象。

        18
  •  -3
  •   Usman Younas    9 年前

    对我来说,对象和实例之间有一点区别

    像:

    第一类OBJ;

    这里,obj是class1的一个实例,它占用堆栈内存。

    class1 obj=新class1();

    在这种情况下,obj是class1的对象,占用堆内存。