2015-08-15 100 views
-2

我有2个班我如何比较两个对象

class Immutable { 
    public int i; 
    public static Immutable create(int i){ 
     return new Immutable(i); 
    } 
    private Immutable(int i){this.i = i;} 
    public int getI(){return i;} 
} 

class Immutable1 { 
    public int i; 
    public static Immutable1 create(int i){ 
     return new Immutable1(i); 
    } 
    private Immutable1(int i){this.i = i;} 
    public int getI(){return i;} 
} 

两者有相同的方法和相同的实例变量。根据我的理解,这个类的状态是相同的(int i),并且两者具有相同的行为(相同数量的方法)

因此,一个是另一个的精确副本。

在,如果我做

Immutable immutable=Immutable.create(1); 
    Immutable1 immutable1=Immutable1.create(1); 
    immutable1=immutable;// I get error here 

的错误是类型不匹配其他类:无法从不可改变转换为Immutable1

+0

我请求后还是downvote – rocking

+0

@ user2864740你可以添加一个答案吗? – rocking

+0

@SotiriosDelimanolis而不是浪费时间编辑我的问题,难道不好回答?你在编辑时没有赚到任何东西,但是我松动了 – rocking

回答

1

Java使用nominative typing(只有名字,什么被宣布为继承/实现什么事)。问题是描述structural typing哪个Java支持而不是

在这种情况下有一个琐碎类型错误,因为在不可变和Immutable1类型之间没有声明主格关系

现在,即使有关系,请记住,只有一个子类型可以隐式分配给超类型;如果没有明确的downcast cast that can fail at run-time,则相反是不可能的。

因此,当且仅当Immutable扩展Immutable1时,当前代码才会是类型有效的 - 即。 class Immutable extends Immutable1 ..


安德烈指出另一种解决方案,我很喜欢,这是有两个类实现相同的interface。这仍然使用nomination类型 - 因为这两个类都只是类型相等的,因为它们都实现了ImmutableInterface - 但是消除了类之间的继承关系。

interface ImmutableInterface { 
    int getI(); 
} 

class Immutable implements ImmutableInterface .. 
class Immutable1 implements ImmutableInterface .. 

// The resulting object types are implicitly upcast to 
// the common (and named) interface type which is trivially assignable to 
// a variable of the same type; no need to worry about subtypes here. 
ImmutableInterface immutable=Immutable.create(1); 
ImmutableInterface immutable1=Immutable1.create(1); 
immutable1 = immutable; 
+0

即使我做不可变延伸immutable1然后也错误**隐式超级构造函数Immutable1()是未定义的。必须显式调用另一个构造函数** – rocking

+0

@rocking在这种情况下,'fix'将在构造函数的顶部添加'super(i);'并且使父构造函数为protected,而不是private。 (搜索引起错误的原因,因为没有重复的短缺。) – user2864740

+0

这两个类都可以实现相同的接口,例如, 'ImmutableInterface'。在这种情况下,不需要修复构造函数。 – Andrey

0

仅仅因为类具有相同的属性和方法声明,它不意味着他们是同一类。对于Java来说,它们非常独特,因为它们有不同的名称。现在,如果你由于某种原因确实需要两个(或更多)不同的类,但也能够以通用的方式使用它们,那么你应该使它们全部都实现一个公共接口。

0

我不知道你为什么想创建两个不同的类来完成相同的事情,并比较一些实例是否等于... 你知道你可以实例化同一个类中的多个对象吗?

那么如果你真的想比较一个Immutable1的实例和一个不可变的实例,你将不得不由你自己决定什么使它们'等于'。例如,你可以尝试

public boolean myCustomEqualMethod(Immutable1 i1, Immutable i2){ 
     return i1.getI()==i2.getI(); 
    } 

更重要的是你不要测试与'='的平等。对于原语类型是“==”和其他对象,你必须调用equals方法:

boolean equalsOrNot="chaine1".equals("chaine2"); 
0

用于比较两个对象,您使用Object类中的equals方法。你想通过创建Immutable类来实现什么。不可变的对象是你不能像Java中的String那样改变的对象。如果你改变它像

String str ="XYZ"; 
str="XZY"; 

什么excatly正在发生的事情是: - STR持有XYZ的内存地址(比如1346),现在海峡拿着这是因为不同的XZY的内存地址(比如6733)字符串是不可变的。

+0

我同意我正在创建不可变的类,但是我的问题即使都具有相同的属性仍然为什么不能都是相同的? – rocking

+0

为2个对象赋予相同的值并不会使其与java相等。对于你而言,这可能与java不相等。为了更好地理解,试着去探索java中HashMap或HashSet中使用的hashCode和equals方法。 –