对象和实例之间的区别
我知道这个问题之前已经被问 过了 ,但是我仍然觉得对于我来说(以及一些/大部分的初学者)来说,答案太模糊了。
我一直在努力教自己更广泛的编程概念,而不是程序和基本的面向对象。 我理解OOP的具体概念(你创build一个具有数据(成员)和函数(方法)的类,然后在运行时实例化该类来实际执行某些事情)。
我想我可以处理一个类是什么types的( 在编译的时候,它就像一个实例被创build的样子的devise蓝图 )。 但是如果是这样的话,什么是对象? 我也知道,在基于原型的语言中,这可能会让事情变得更糟糕,但也许这就是为什么需要在脑海中清楚区分对象和实例的原因。
除此之外,我还与“对象”和“实例”的概念斗争。 我读过的很多资源(包括SO的答案)都说它们大体上是相同的,而且它们的区别在于语义。 其他人说,两者之间有一个真正的概念上的区别。
SO的专家能帮助初学者在OOP的世界里有那个“啊哈”的时刻吗?
再次感谢。
注意:这不是作业,我不上学 – 但是,我认为这会帮助那些正在寻找功课帮助的人。
房屋devise蓝图就像一个类的描述。 所有从这个蓝图build造的房子都是这个阶级的对象。 给定的房子是一个例子。
事实上,面向对象编程通常会造成哲学发展方面与计算机的实际机械运作之间的脱节,从而造成混乱。 我会尽力为你比较两个:
OOP的基本概念是:Class >> Object >> Instance。
class级=蓝图。 该对象是一个基于“蓝图”(如房子)build立的实际的东西。 实例是对象的虚拟副本(但不是实际副本)。
对“实例”更技术性的解释是它是“内存引用”或引用variables。 这意味着一个“实例”是一个内存中只有一个对象的内存地址的variables。 它所处理的对象是实例被称为“实例”的同一个对象。 如果你有一个对象的许多实例,你真的只是在你的内存中的不同位置有很多variables,它们都有相同的确切的内存地址 – 这些都是相同的确切对象的地址。 尽pipe在代码中看起来像是可以的,但不能“更改”实例。 当你改变一个实例时,你真正做的是直接改变原始对象。 在电子方面,处理器在更改原始对象的数据之前会经过内存(参考variables/实例)中的一个额外位置。
过程是:处理器>>实例的内存位置>>原始对象的内存位置。
请注意,使用哪个实例并不重要 – 最终结果将始终相同。 所有的实例将继续在其内存位置(对象的内存地址)中保持相同的确切信息,并且只有对象将会改变。
阶级与对象之间的关系有点混乱,尽pipe在哲学上它是最容易理解的(蓝图>>房子)。 如果对象是存储在内存中的实际数据,什么是“类”? 事实certificate,机械的对象是类的精确副本。 所以这个类只是内存中其他地方的另一个variables,它保存了与对象相同的确切信息。 注意关系之间的区别:
对象是类的副本 。 实例是保存对象的内存地址的variables。
你也可以有同一个类的多个对象,然后每个对象有多个实例。 在这些情况下,每个对象的实例集在值上是等价的,但是对象之间的实例不是。 例如:
让类A从类A让Object1,Object2和Object3。
// Object1与object2和object3具有相同的精确值,但在内存中的不同位置。
从Object1 >> let obj1_Instance1,obj1_Instace2,obj1_Instance3
//所有这些实例在内存中的价值和不同位置也是等价的。 它们的值= Object1.MemoryAddress。
等等
当你开始介绍types时,事情变得更加复杂。 这里是一个使用c#types的例子:
//假定类Person存在Person john = new Person();
实际上,如果将其分解为两部分,则该代码更易于分析:
Person john; john = new Person();
在技术上讲,第一行'声明一个Person types的variables。 但是,这是什么意思?? 一般的解释是我现在有一个只能容纳一个Person对象的空variables。 但等一下 – 它是一个空的variables! 这个variables的内存位置没有任何东西。 事实certificate,“types”在机械上是毫无意义的。 types最初是作为一种pipe理数据的方式发明的,没有别的。 即使当你声明原始types如int,str,chr(没有初始化它)时,计算机中也没有任何反应。 编程的这种奇怪的语法方面是人们认为类是对象蓝图的一部分。 OOP更容易混淆委托types,事件处理程序等types。我会尽量不要过多地关注它们,只记得它们都是错误的。 直到它变成一个对象或者被设置为一个对象的内存地址之前,variables都不会改变。
第二行也有点混乱,因为它同时做了两件事:
首先评估右边的“新人()”。 它创build了一个Person类的新副本 – 也就是说,它创build了一个新的对象。
之后评估左边的“john =”。 它将john变成一个引用variables,给它刚才在同一行右边创build的对象的内存地址。
如果你想成为一名优秀的开发人员,重要的是要了解,没有任何计算机环境的工作基于哲学理想。 计算机甚至不那么合乎逻辑 – 它们实际上只是使用基本布尔逻辑电路(主要是NAND和OR)粘合在一起的大量电线。
对象是内存中的东西,而实例是引用它们的东西。 在上面的图片中:
- std(实例) – >学生对象(右)
- std1(实例) – >学生对象(左)
- std2(实例) – >学生对象(左)
- std3(instance) – > no object(null)
“ 类”这个词来自“ 分类” ( 放入某个东西的类别 ),现在我们都听说一个类就像是一个蓝图,但这到底意味着什么呢? 这意味着该类拥有一个特定类别的描述,( 我想用Java的例子来展示类,对象和实例之间的区别,并且我会请求读者在阅读它时将它看作是一个故事,如果你不熟悉java也无所谓 )所以让我们先从make一个名为HumanBeing的类 开始 ,所以Java程序会expression如下
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; } }
现在我们已经把行为添加到了我们的类别HumanBeing中 ,所以我们可以要求它的名字,年龄,身高,体重,但是你会问谁来这些细节,因为class HumanBeing
只是一个类别,它是一个蓝图,例如一个build筑师在他想build造的build筑物的纸上画蓝图,现在我们不能住在蓝图( 对build筑物的描述 )中,我们只能在build筑物build造后才能住在这里所以在这里我们需要从我们的类别中build立一个人我们已经在上面描述了,所以我们如何在Java中做到这一点
class Birth{ public static void main(String [] args){ HumanBeing firstHuman = new HumanBeing("Adam",25,6.2,90); } }
现在在上面的例子中,我们创build了第一个名字年龄身高的人类,那么上面的代码到底发生了什么? 。 我们正在实例化我们的类别HumanBeing即我们的类的一个对象被创build
注意: 对象和实例不是同义词在某些情况下,对象和实例似乎是同义词,但它们不是,我会给出这两种情况
案例1:对象和实例似乎是同义词
让我详细说一下,当我们说HumanBeing firstHuman = new HumanBeing("Adam",25,6.2,90);
我们类的一个对象是在堆内存上创build的,并且有一个地址被分配给它,并且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()); ... ... } }
所以我们有第一个人,让我们的第一个人有一定的资格让羽毛动起来,让我们让他成为一名医生,所以我们需要一个名为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*/ } }
在这里,我们使用了inheritance的概念,它在代码中带来了一些可重用性,每个Doctor都将首先是一个HumanBeing,所以Doctor将有一个名字,年龄,权重,高度,这个名字将会从HumanBeinginheritance而不是再次写入,注意我们刚刚写了一个我们还没有创build的医生的描述,所以让我们在我们的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:对象和实例不是同义词
在上面的代码中,我们可以想象我们正在实例化我们的类Doctor,并将其带入生活,即我们只是创build一个类Doctor对象 ,因为我们已经知道Object在堆内存上创build , firstDoctor
持有对该对象的引用堆;
这个特定的对象firstDoctor
如下所示(请注意firstDoctor
拥有对象的引用,它不是对象本身)
-
firstDoctor
是class Doctor
一个对象和一个class Doctor
的实例 -
firstDoctor
不是class HumanBeing
的对象,而是class HumanBeing
的实例
所以一个特定的对象可以是一个特定类的实例,但不一定是该类的对象
结论:
如果对象满足该特定类别的所有特征,则称该对象为特定类别的实例
现实世界的例子如下,我们是第一次出生,人类如此形象我们作为人类的对象,现在,当我们长大了,我们承担责任,学习新的技能,在生活中扮演不同的angular色榜样儿子,兄弟,女儿,父亲,妈妈现在我们究竟是什么?我们可以说我们是人类的对象,但是兄弟,女儿……等等的实例
我希望这有帮助
谢谢
一个对象是一个类的实例(对于基于类的语言)。
我认为这是我能想出的最简单的解释。
一个类定义一个对象。 你可以在许多语言中进一步说,一个接口定义了对象之间的通用属性和方法。
一个对象是可以代表真实世界中的东西的东西。 当你希望对象实际上代表真实世界中的东西时,必须实例化对象。 实例化意味着你必须通过一个构造函数来定义这个特定对象的特性(属性)。
一旦你定义了这些特征,你现在就拥有了一个对象的实例。
希望这清除了事情。
我认为重要的是指出通常有两件事。 蓝图和副本。 人们倾向于命名这些不同的东西; 类,对象,实例只是人们使用的一些名称。 重要的是有蓝图和副本 – 不pipe他们的名字。 如果你已经理解了这两个,就避免其他让你困惑的事情。
我想最好的答案已经被放弃了。
class级是蓝图,对象是build筑物,或者蓝图的例子也为我做了诀窍。
有时,我想认为类是模板(就像在MS Word中),而对象是使用模板的文档。
“一个类描述了一组称为它的实例的对象。” – 施乐学习研究小组,“Smalltalk-80系统”,Byte Magazine Volume 06 Number 08,p39,1981。
什么是对象?
一个对象是一个类的一个实例。 通过在你身边find真实世界的例子可以最好地理解对象。 你的桌子,你的笔记本电脑,你的车都是很好的现实世界的例子。
真实世界对象有两个特点,它们都有状态和行为。 人类也是一个客体的好例子,我们人类有状态/属性 – 名字,身高,体重和行为 – 走路,奔跑,说话,睡觉,代码: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
定义了Car对象与外界的行为。
参考文献:
- 什么是对象?
- 什么是课堂?
让苹果比较苹果。 我们都知道苹果是什么。 它看起来像什么 它的味道是什么 那是一堂课。 这是一个事物的定义。 这是我们所知道的一件事情。
现在去找一个苹果。 这是一个例子。 我们可以看到它。 我们可以品尝它。 我们可以用它做事情。 这是我们所拥有的。
类=我们所知道的东西。 一个定义。
对象/实例=符合我们所能定义的东西,可以做的事情。
在某些情况下,术语“对象”可能被用来描述一个实例,但在其他情况下,它被用来描述一个实例的引用 。 术语“实例”仅指实际的实例。
例如,一个List可以被描述为一个对象的集合,但是它实际上拥有的是对象实例的引用。
我一直喜欢这样一个想法,即将一个类的定义等同于“抽象数据types”的定义 。 也就是说,当你定义一个类的时候,你正在定义一个新types的“东西”,他的数据types表示,在原语和其他“东西”方面,他的行为在function和/或方法方面。 (抱歉的一般性和forms主义)
无论何时定义一个类,当你实例化和/或创build一个特定的对象时,你都会打开一个新的可能性来定义某些实体的属性和行为。
有时,术语对象和实例是可以互换的。 一些面向对象的纯粹主义者会认为一切都是对象,我不会抱怨,但在真正的面向对象的世界里,我们的开发者使用两个概念:
- 类:抽象数据types您可以从中派生其他ADT和创build对象的示例。
- 对象:也称为实例,表示由给定的抽象数据types表示的数据结构和函数的特定示例。
面向对象编程是一个系统的隐喻 ,可以帮助你组织你的程序需要处理的知识,这样可以使你更容易开发你的程序。 当你select使用面向对象程序devise时,你会select你的面向对象程序devise语言(OOP-Googles),并且你决定通过发送消息来看到真实世界的问题。 而不是看到一个盖伊驾驶一辆车,你看到一个盖伊发送一条消息,指示他想要汽车做什么。 汽车是一个很大的对象,并会通过发送消息给它的引擎来响应这个消息,或者它能够正确地响应司机告诉他在消息中做的事情等。
在创build系统隐喻之后,您将所有现实都看作是发送消息的对象,您决定将所有与您的问题域相关的东西都放在PC中。 在那里你会注意到有很多伙计们驾驶着不同的牌,并且分别编程他们每个人的行为是没有意义的,因为他们的行为都是一样的。所以你可以说两件事:
- 所有这些人都以相同的方式行事,所以我将创build一个名为Driver的类,它将指定世界上的所有驱动程序是谁行为的,因为它们的行为都是一样的。 (而你正在使用基于类的OOP)
- 或者你可以说嘿! 第二个Driver的行为与第一个Driver相同,只是他喜欢快一点。 第三个司机的行为与第一个司机的行为相同,只不过他开车时喜欢曲折。 (你使用基于原型的OOP)。
然后,你开始在计算机上放置所有驱动程序的行为方式(或第一个驱动程序的行为方式,以及第二个和第三个驱动程序的不同之处),然后在一段时间之后获得程序,然后使用代码创build三个驱动程序,这些驱动程序是您在该PC中使用的模型,以反驳您在现实世界中看到的驱动程序。 在PC中创build的3个驱动程序是原型的实例(实际上第一个是原型,第一个可能是原型,取决于你如何build模),或者你创build的类。 实例和对象之间的区别在于,对象是您在现实世界中使用的隐喻。 你select把这个家伙和汽车看作是对象(把它们看作是实例)是合作的。 然后你用它作为灵感来创build你的代码。 在创build原型或类之后,该实例只存在于您的程序中。 “对象”存在于PC之外,因为它使用映射来将现实世界与程序联合起来。 它将Guy与您在PC中创build的Driver实例相结合。 所以对象和实例是非常相关的,但它们并不完全相同(一个实例是程序中对象的“腿”,另一个“腿”是在现实世界中)。
在此线程中扩展前面给出的示例之一…
考虑一个场景 – 有一个要求,5个房屋需要在居民区build成。 所有5个房屋共享一个共同的build筑结构。 build筑结构是一个类 。 房子是一个对象 。 每个住在里面的人都是一个例子 。
对象:当我们创build一个对象的时候,一些内存被这个对象所占用:Test t = new Test(); //这里t是Test类的一个对象
实例:当我们声明实例单独的内存没有被该实例占用时:Test t; //这里t是Test类的实例
简单地说,对象是一个不分配内存的唯一声明。 而实例是分配内存的类的一个对象。
对我而言,对象和实例之间有一个小的区别
喜欢 :
class1 obj;
在这里,obj是占用堆栈内存的class1的一个实例
class1 obj = new class1();
在这种情况下,obj是class1的一个对象,占用了堆内存