对象和实例之间的区别

TCC*_*CCV 76 oop

我知道之前已经提出 这样的问题,但我仍然觉得答案对我来说太模糊了(而且,有些/大多数初学者).

我一直在努力教自己更广泛的编程概念,而不是程序和基本的OOP.我理解OOP的具体概念(你创建一个具有数据(成员)和函数(方法)的类,然后在运行时实例化该类以实际执行某些事情,那种事情).

我认为我可以处理类的内容(在编译时以类似的方式创建实例的设计蓝图).但如果是这样的话,对象是什么?我也知道在基于原型的语言中,这可能会使事情变得更糟,但也许这就是为什么在我的脑海中需要明确区分对象和实例.

除此之外,我还在努力解决"对象"和"实例"的概念.我读过的很多资源(包括SO的答案)都说它们大致相同,而且区别在于语义.其他人说两者之间存在真正的概念差异.

SO的专家能帮助初学者在OOP世界中有一个"啊哈"的时刻吗?

再次感谢.

注意:这不是家庭作业,我不上学 - 但是,我认为这有助于那些正在寻找家庭作业帮助的人.

joe*_*der 124

房屋设计的蓝图就像一个阶级描述.从该蓝图建造的所有房屋都是该类别的对象.给定的房子是一个实例.

  • 而静态方法就像所有房屋共享的实用工具. (15认同)
  • 此外,还有一条来自我家乡的街道,因为有8个相同的砖房连成(在"住房开发"的概念出现之前),因此有一点点的地方名气.所以我可以非常好地想象."班级"是建筑师制定的.完成的房屋是"物体",因为它们都是完全相同的.每个房子都是一个"实例",因为他们已经(并且可以继续)从那时起以不同的方式处理[现在一个人有壁板:o(]. (4认同)
  • 不是对象和实例完全相同吗? (4认同)
  • 但是,根据蓝图建造的房屋不是实例吗? (2认同)

小智 38

事实是,面向对象的编程经常通过在开发的哲学方面和计算机的实际机械工作之间建立脱节而产生混淆.我会尝试将两者对比为你:

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

该类=蓝图.对象是基于"蓝图"(如房子)构建的实际内容.实例是对象的虚拟副本(但不是真实副本).

"实例"的更多技术解释是它是"内存引用"或引用变量.这意味着'instance'是内存中的变量,只有一个对象的内存地址.它所对应的对象是该实例被称为"实例"的同一对象.如果你有一个对象的很多实例,你真的只有很多变量在你的内存中的不同位置,它们都有相同的确切内存地址 - 这是同一个确切对象的所有地址.你不能"改变"一个实例,尽管你的代码看起来很像.当您"更改"实例时,您真正要做的是直接更改原始对象.在电子方面,处理器在更改原始对象的数据之前经历内存中的一个额外位置(引用变量/实例).

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

请注意,使用哪个实例无关紧要 - 最终结果将始终相同.所有实例将继续在其内存位置(对象的内存地址)中保持相同的确切信息,并且只有对象才会更改.

类和对象之间的关系有点混乱,虽然在哲学上它是最容易理解的(蓝图>> house).如果对象是存储在内存中的实际数据,那么什么是"类"?事实证明,机械上的对象是类的精确副本.因此,类只是内存中其他位置的另一个变量,它保存与对象相同的确切信息.注意关系之间的区别:

对象是类的副本.Instance是一个保存对象内存地址的变量.

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

让A类中的A类使用Object1,Object2和Object3.

// Object1与object2和object3具有相同的确切值,但它们位于内存的不同位置.

来自Object1 >> let obj1_Instance1,obj1_Instace2,obj1_Instance3

//所有这些实例在值和内存中的不同位置也是等价的.它们的值= Object1.MemoryAddress.

等等

当你开始介绍类型时,事情变得更加混乱.以下是使用c#类型的示例:

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

实际上,如果将代码拆分为两部分,则此代码更易于分析:

Person john;
john = new Person();
Run Code Online (Sandbox Code Playgroud)

在技​​术方面,第一行'声明一个Person 类型的变量.但是,这是什么意思??一般的解释是我现在有一个只能容纳Person对象的空变量.但等一下 - 它是一个空变量!变量内存位置没有任何内容.事实证明,"类型"在机械上毫无意义.类型最初是作为一种管理数据的方式而发明的.即使你声明了原始类型,如int,str,chr(没有初始化它),计算机内也没有任何事情发生.这种奇怪的编程语法方面是人们认为类是对象蓝图的一部分.对于具有委托类型,事件处理程序等的类型,OOP变得更加混乱.我不会过多地关注它们,只记得它们都是用词不当.在变量成为对象或设置为对象的内存地址之前,变量不会发生任何变化.

第二行也有点令人困惑,因为它同时做了两件事:

首先评估右侧"new Person()".它创建了Person类的新副本 - 也就是说,它创建了一个新对象.

然后在此之后评估左侧"john =".它将john转换为引用变量,为其提供刚刚在同一行右侧创建的对象的内存地址.

如果你想成为一名优秀的开发人员,重要的是要理解没有任何计算机环境能够基于哲学理想而工作.计算机甚至不合逻辑 - 它们实际上只是使用基本布尔电路(主要是NAND和OR)粘合在一起的大量电线.


Pus*_*ari 25

Class这个词来自于分类(放入某个东西类别),现在我们都听说过一个就像一个蓝图,但这究竟意味着什么?这意味着Class拥有特定类别的描述,(我希望通过使用Java的示例显示Class,Object和Instance之间的区别,我会要求读者在阅读时将其可视化为Story,如果你不熟悉Java没关系),那么,让我们开始做一个分类HumanBeing,因此Java程序表达如下它

class HumanBeing{ 
   /*We will slowly build this category*/ 
}
Run Code Online (Sandbox Code Playgroud)

现在HumanBeing的一般属性名称,年龄,身高,体重现在让我们将自己限制为这四个属性,让我们将它添加到我们的类别

class HumanBeing{
    private String Name;
    private int Age;
    private float Height;
    private float Weight; 

   /*We still need to add methods*/

}
Run Code Online (Sandbox Code Playgroud)

现在每个类别都有一个行为,例如类别Dog有行为吠叫,获取,滚动等...,同样我们的类别HumanBeing也可以有某些行为,例如当我们问我们的HumanBeing你的名字/年龄/体重/高度?它应该给我们它的名字/年龄/体重/身高,所以在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;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我们已经在我们的类别HumanBeing中添加了行为,因此我们可以询问它的名称,年龄,身高,体重,但是您会向谁询问这些细节,因为class HumanBeing它只是一个类别,它是一个蓝图,例如建筑师制作蓝图他想要建造的建筑物的纸张,现在我们不能继续生活在蓝图中(它对建筑物的描述)我们只能在建筑物中生活了所以在这里我们需要从我们的类别中创造一个人类,我们如上所述,那么我们如何在Java中做到这一点

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

现在在上面的例子中,我们创建了第一个名字年龄身高的人,那么上面的代码到底发生了什么?.我们正在实例化我们的类别HumanBeing,即创建了我们类的对象

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

情况1:对象和实例似乎是同义词
让我详细说明一下,当我们说在堆内存上创建了我们类别HumanBeing firstHuman = new HumanBeing("Adam",25,6.2,90); 的对象并且为它分配了一些地址,并且保存了对该地址的引用,现在这个对象是HumanBeing的目的,也HumanBeing的一个实例.这里似乎对象和实例是同义词,我会重复自己,它们不是同义词firstHuman

让我们继续我们的故事,我们创造了我们的第一个人类,现在我们可以问他的名字,年龄,身高,体重,这就是我们在Java中的表现

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());
    ...
    ...  
  }
}
Run Code Online (Sandbox Code Playgroud)

所以我们有第一个人类,让我们通过给我们的第一个人类一些资格来移动羽毛,让我们让他成为博士,所以我们需要一个名为Doctor的类别并给我们的Doctor一些行为,所以在java中我们做如下

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*/
   }
}  
Run Code Online (Sandbox Code Playgroud)

在这里,我们使用了继承的概念,它在代码中带来了一些可重用性,每个Doctor都将首先成为HumanBeing,因此A Doctor将具有Name,Age,Weight,Height,它将继承HumanBeing而不是再次编写,请注意,我们刚刚写了一个我们尚未创建的医生的描述,所以让我们在我们的医生中创建一个医生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*/
    .......
    .......    
  }
}
Run Code Online (Sandbox Code Playgroud)

案例2:对象和实例不是同义词
在上面的代码中,我们可以看到我们正在实例化我们的类别Doctor并将其变为现实,即我们只是创建一个类别对象Doctor,因为我们已经知道对象是在堆内存上创建的firstDoctor在堆上保存对该Object的引用;

这个特定的对象firstDoctor如下(请注意firstDoctor保留对象的引用,它不是对象本身)

  1. firstDoctor一个对象class Doctor一个实例class Doctor
  2. firstDoctor不是一个对象class HumanBeing,但实例class HumanBeing

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

结论:

如果Object满足特定类别的所有特征,则称该对象是特定类别的实例

现实世界的例子将如下,我们第一次出生为人类,所以我们形象为人类的对象,现在我们长大后,我们承担责任,学习新技能,在生活中发挥不同的作用.儿子,兄弟,女儿,父亲,妈妈,我们现在实际上是什么?我们可以说我们是人类的对象,但兄弟,女儿,......等等

我希望这有帮助

谢谢

  • ...为什么我们这个答案只有3个赞成票? (5认同)

Tru*_* Ha 12

在此输入图像描述

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

  • std(实例) - >学生对象(右)
  • std1(实例) - >学生对象(左)
  • std2(实例) - >学生对象(左)
  • std3(实例) - >没有对象(null)

  • Truong,你的回答是错误和混乱的.实际上,实例是从基类对象派生的对象.实例==对象.这个术语很好地解释了例如[this](http://stackoverflow.com/questions/2290422/what-is-the-difference-between-object-and-instance#2296182)或[this](http:/ /stackoverflow.com/questions/2290422/what-is-the-difference-between-object-and-instance#2291192)回答. (6认同)
  • 那样太好了.我真的很喜欢它的低级别.关于我是否比这个类比更喜欢这个,我会来回走动.我认为一起了解2是我真正需要的.upvote,但不确定我是否可以给你答案,因为它已经给了Joe.谢谢你.这清除了很多. (3认同)

suk*_*kru 5

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

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

  • 我同意你的解释与我一直在阅读的方式是正确的,但是网上有很多条目对两者进行了区分。我不知道如果没有一种语言,这种问题是否无法回答(哇,一个元问题,这个问题是一个类,如果不用语言实例化它就无法使用,哈哈)。 (2认同)

Der*_*itz 5

类定义了一个对象.您可以进一步使用多种语言,并说接口定义了对象之间的公共属性和方法.

对象可以代表现实世界中的某些东西.当您希望对象实际表示现实世界中的某个对象必须实例化时.实例化意味着您必须通常通过构造函数定义此特定对象的特征(属性).

一旦定义了这些特征,您现在就拥有了一个对象的实例.

希望这可以解决问题.

  • 以上乔说,所有从蓝图建造的房屋都是物体.真正.他说一个特定的房子就是一个例子.真正.但是,所有的房屋都是实例,给定的房屋也是一个对象.如果没有,他就会有所作为.在代码中,有必要在构造对象和实例时区分它们.我们说它是在实际构建时实例化的.一个常见问题可能是:您是否记得实例化对象?即.如果您在声明对象后忘记调用构造函数. (3认同)