OOP中的身份和平等有什么区别?

OOP(面向对象编程)中的身份和平等有什么区别?

  • 身份:一个variables与另一个variables保持相同的实例。

  • 平等:两个不同的对象可以互换使用。 他们经常有相同的ID。

例如:

Integer a = new Integer(1); Integer b = a; 

ab相同。

 Integer c = new Integer(1); Integer d = new Integer(1); 

cd相等但不相同。

当然,两个相同的variables总是相等的。

在Java中,相等是由equals方法定义的。 请记住,如果你实现equals,你还必须实现hashCode 。

身份确定两个对象是否共享相同的内存地址。 平等决定两个对象是否包含相同的状态。

如果两个对象是相同的,那么它们也是相等的,但仅仅因为两个对象是相等的,并不意味着它们共享相同的存储器地址。

对于string有一个特殊的情况,但这是一个脱离主题,你需要问别人有关如何工作确切;-)

身份意味着它是相同的对象实例,而等于意味着您比较的对象是对象的不同实例,但碰巧包含相同的数据。

插图(在Java中)

 Date a = new Date(123); Date b = new Date(123); System.out.println(a==b); //false System.out.println(a.equals(b)); //true 

所以a和b是不同的实例(内存中的不同分配),但是在“数据”级别上它们是相等的。

考虑“相同”和“等同”这两个字。 如果两件事是相同的,它们具有相同的身份; 他们是一样的东西。 如果它们是相同的,则可以替代另一个而不影响结果; 他们有相同的行为和属性。

例如,

在StackOverFlow中:

  • 身份:我是迈克尔,你是塞万加拉扬,所以我们不一样。

  • 平等:如果我们有相同的信誉分数,我们在某些方面是平等的。

在Java和类似的语言中“泄露”对象引用的抽象,你可以testing两个引用是否引用同一个对象。 如果他们引用同一个对象,那么引用是相同的。 在Java中,这是==运算符。

还有一个equals方法用于testing两个对象是否具有相同的值,例如当用作HashSet键时(相等对象的哈希码也应该相等)。 当客户端代码使用时,相同的对象应该具有相同的“值”和语义。

Purer面向对象的语言没有标识符比较,因为客户端代码通常不应该关心两个对象是否具有相同的内存地址。 如果对象表示相同的现实世界的实体,那么使用一些ID或者键值而不是身份来更好地build模,然后该实体成为等价合同的一部分。 不依赖于对象的内存地址来表示真实世界的标识,从而简化了caching和分布式行为,并且抑制了==会在string比较中删除大量的错误,或者在Java中对一些基元进行装箱。

标识:对同一个对象的两个引用( o1 == o2 )。

平等:方法o1.equals( o2 )返回true 。 这并不一定意味着这两个对象包含(全部)相同的数据。

从理论上讲,即使对于相同的对象,也可以重写equals()方法来返回false 。 但是这会破坏Object.equals()的规范:

equals方法在非null对象引用上实现等价关系:

  • 它是自反的:对于任何非空引用值x,x.equals(x)应该返回true。
  • 它是对称的:对于任何非空引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)才返回true。
  • 它是可传递的:对于任何非空引用值x,y和z,如果x.equals(y)返回true,y.equals(z)返回true,则x.equals(z)应该返回true。
  • 这是一致的:对于任何非空引用值x和y,如果在对象的等值比较中没有使用修改的信息,那么x.equals(y)的多个调用始终返回true或始终返回false。
  • 对于任何非null的引用值x,x.equals(null)应该返回false。

For primitive types ( int , boolean , char, long , float ... )
==和!=是平等testing

and for Objects
==和!=是身份testing。 [只比较参考]

equals方法用于对象的相等性testing[可以重写比较特定属性]

我在这个http://www.cs.cornell.edu/courses/cs211/2006sp/Lectures/L14-Comparison/L14cs211sp06.pdf上find了一篇很好的文章。;

http://ocw.mit.edu/NR/rdonlyres/Electrical-Engineering-and-Computer-Science/6-170Fall-2005/D659DC53-FB1D-403C-8E35-2CAECBED266E/0/lec12.pdf

引用
我喜欢猪。 狗看着我们。 猫看不起我们。 猪对待我们是平等的。 :d
Sir Winston Churchill

身份概念是相当哲学的,这就是为什么你不应该只参考它。

你可以说,两个身份是相同的,如果第一个变化反映在第二个,反之亦然。 当然,这也包括共享相同的内存地址,但是一般而言,身份与对象的属性相关,只要两个对象相同,但是不包括身份,等同性就用来检查。

反之亦然,如果两个项目具有相同的身份,他们也是平等的(平等互换)。

只有在variablesxy引用相同的对象时, x == y为真。

x.equals(y)取决于x.equals()的实现,而且通常比上面那样严格,因为它比较了对象的内容。 (在Java中,如果x.equals(y) ,它也必须是真正的x.hashCode() == y.hashCode();

例:

 Integer w = new Integer(3); Integer x = new Integer(1); Integer y = x; Integer z = new Integer(1); // all of these evaluate to true y.equals(x) // it's the same object, of course the content is same x.equals(z) // different objects, same content (`1`) z.equals(y) !w.equals(x); // the content is different (`3` vs `1`) !w.equals(y); !w.equals(z); x == y // same object z != x // different objects y != z w != x 

看看我的video,这解释了身份和平等之间的区别很好,包括两个一步一步的编码示例: https : //www.youtube.com/watch?v=OOpO46_k7Uo