Question

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);
}

This prints false, despite both objects being the same thing. Changing return this == n to return this.intType == n.intType yields error "cannot find symbol: variable intType, location: variable n of type Numbers".

I'm fairly new to ADT and still making my way around it, so excuse me if this is a simple question. I'm not sure why it doesn't work, however, and why I cannot reference n.intType but I can this.intType.

Was it helpful?

Solution

intType is declared on NumbersType but n is a Numbers. So you can't necessarily compare them.

Now, one thing you could do is create a method on the interface that retrieves some value. I say 'some' value instead of 'the' value because the other Numbers may be some other implementation. This is an important aspect of interfaces. If you have a Numbers you cannot know that it is actually a NumbersType. (You can find that out with instanceof but this would not be a good way to program an interface implementation. The interface's declaration should specify its interactions entirely.)

But first there's kind of a side issue which is that you're declaring an overload of Object#equals. You might be intending to declare an override which is a different thing. For the purpose of my answer, I am going to show an example of both and name the overload something different.

Now here's the modified interface:

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

Now that you can retrieve the int, you can compare them in the implementation class.

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);
    }
}

You may want to read:

If you are just learning this stuff, equals may not be a method you should be trying to implement. It is contractual and easy to get wrong.

Another complication is declaring equals in terms of interfaces: because equals must be symmetric, the implementations must override it identically. Otherwise the contract is broken.

OTHER TIPS

  1. Your class is NumbersType not Numbers, so you should type cast a and b in your equals method. This is why you cannot do n.intType

  2. After you type cast, your equals method should compare intTypes of the objects, not direct references. This is why it will not work.

Your naming is a little bit confusing and I would suggest studying Polymorphism in general.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top