【问题标题】:Comparison between abstract objects yields wonky error抽象对象之间的比较会产生不稳定的错误
【发布时间】:2014-03-09 01:25:59
【问题描述】:
Numbers a,b;
a = new NumbersType(1);
b = new NumbersType(1);
System.out.println(a.equals(b));

public class NumbersType implements Numbers {
    int intType;
    public NumbersType (int q) {
        this.intType = q;
    }
    public boolean equals(Numbers n) {
        return this == n;
    }
}

public interface Numbers {
    public boolean equals(Numbers n);
}

尽管两个对象是同一个东西,但这会打印错误。将 return this == n 更改为 return this.intType == n.intType 会产生错误“找不到符号:变量 intType,位置:数字类型的变量 n”。

我对 ADT 还很陌生,并且仍在努力解决它,如果这是一个简单的问题,请原谅。但是,我不确定为什么它不起作用,以及为什么我不能引用 n.intType 但我可以 this.intType

【问题讨论】:

  • 始终将equals 实现为equals(Object)。不要给它另一个参数类型。这不是直接的问题,但会导致其他令人讨厌的问题。
  • @user2357112, Numbers 是一个对象。
  • 没关系。如果你给你的方法签名equals(Number),那么Object o1 = someNumber; Object o2 = someOtherNumber; o1.equals(o2);会调用错误的方法。

标签: java abstract-data-type


【解决方案1】:

intTypeNumbersType 上声明,但nNumbers。所以你不一定能比较它们。

现在,您可以做的一件事是在接口上创建一个方法来检索一些值。我说 'some' 值而不是 'the' 值,因为另一个 Numbers 可能是其他一些实现。这是接口的一个重要方面。如果你有一个Numbers,你就无法知道它实际上是一个NumbersType。 (您可以通过instanceof 找到这一点,但这不是编程接口实现的好方法。接口的声明应该完全指定它的交互。)

但首先有一个附带问题,即您声明了 Object#equals 的重载。您可能打算声明一个覆盖,这是另一回事。出于回答的目的,我将展示两者的示例并将重载命名为不同的名称。

现在是修改后的界面:

public interface Numbers {
    public int getIntType();
    public boolean isIntTypeEqual(Numbers n);
}

现在你可以检索 int,你可以在实现类中比较它们。

public class NumbersType
implements Numbers {
    private int intType;

    public NumbersType(int intType) {
        this.intType = intType;
    }

    @Override
    public int getIntType() {
        return intType;
    }

    @Override
    public boolean isIntTypeEqual(Number n) {
        return intType == n.getIntType();
    }

    // overriding hashCode because we are overriding equals
    @Override
    public int hashCode() {
        return intType;
    }

    @Override
    public boolean equals(Object o) {
        if(!(o instanceof Numbers))
            return false;

        return isIntTypeEqual((Numbers)o);
    }
}

您可能想阅读:

如果您只是学习这些东西,equals 可能不是您应该尝试实施的方法。它是契约性的,容易出错。

另一个复杂之处是在接口方面声明 equals:因为 equals 必须是对称的,所以实现 必须 相同地覆盖它。否则合同失效。

【讨论】:

  • 谢谢,这解决了一切。我有很多阅读要做。
  • 没问题。继续阅读,如果您需要帮助,当然可以提出问题。
【解决方案2】:
  1. 你的类是 NumbersType 而不是 Numbers,所以你应该在你的 equals 方法中输入 cast a 和 b。这就是为什么你不能这样做n.intType

  2. 键入 cast 后,equals 方法应该比较对象的 intTypes,而不是直接引用。这就是它不起作用的原因。

你的命名有点混乱,我建议一般研究多态性。

【讨论】:

  • ab 初始化为NumbersType 并不能解决问题。我仍然遇到同样的错误。
  • @riista 你真的在比较 intTypes 吗?而且上面的 user2357112 也是对的,这不是您在 Object 类中覆盖 equals 方法的方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-05
  • 2012-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-23
相关资源
最近更新 更多