0

I need to write abstract class, which looks like this.

public abstract class Value {

public abstract String toString();
public abstract Value add(Value v);
public abstract Value sub(Value v);
public abstract boolean eq(Value v);
public abstract boolean lte(Value v);
public abstract boolean gte(Value v);
public abstract boolean neq(Value v);
public abstract boolean equals(Object other);
public abstract int hashCode();
public abstract Value create(String s);

}

Now I need to make few classe, which inherit from that one. I started from Int class and implemented it like this:

public class Int extends Value {

int val;

public String toString() {
    String toStr = Integer.toString(val);
    return toStr;
}

public Int add(Value v) {
    Int result = new Int();
   if(v instanceof Int) {
        Int temp = (Int) v;
        result.val = val + temp.val;
    }

    return result;
}

public Int sub(Value v) {
    Int result = new Int();
    if(v instanceof Int) {
        Int temp = (Int) v;
        result.val = val - temp.val;
    }
    return result;
}

public boolean eq(Value o) {
    if(this == o) return true;
    if(this == null) return false;
    if(getClass() != o.getClass()) return false;
    Int other = (Int) o;
    return toString() == other.toString();
}

public boolean lte(Value v) {
    if(v instanceof Int) {
        Int temp = (Int) v;
        return this.val < temp.val;
    }
    return false;
}

public boolean gte(Value v) {
    if(v instanceof Int) { 
        Int temp = (Int) v;
        return this.val > temp.val;
    }
    return false;
}

public boolean neq(Value v) {
    if(v instanceof Int) {
        Int temp = (Int) v;
        return !eq(temp);
    }
    return true;
}

public boolean equals(Object o) {
    if(this == o) return true;
    if(this == null) return false;
    if(getClass() != o.getClass()) return false;
    Int other = (Int) o;
    return toString() == other.toString();
}

public int hashCode() {
    Integer hash = val;
    return hash.hashCode();
}

public Int create(String s) {
    val = Integer.parseInt(s);
    return this;
}

}

Everything is compiling and working, but I have no clue if my hashcode() function and equals() are good. Furthermore i want to use create() to make objects like this:

getInstance().create("1234");

Is my method also sufficient?

4 Answers4

1

The hashCode() method is fine (although I'd add an @Override annotation, just to make the code easier to maintain and avoid mistakes), but the equals(Object) definitely isn't.

Following the logic you have in place, == isn't the right way to compare strings. You should use equals instead (see, e.g., How do I compare strings in Java?). In addition, as Joakim Danielson noted in the comments, this can never be null - you should check if o is null instead:

public boolean equals(Object o) {
    if (this == o) {
        return true;
    }
    if (o == null) {
        return false;
    }
    if(getClass() != o.getClass()) {
        return false;
    }
    Int other = (Int) o;
    return toString().equals(other.toString()); // Here!
}

But in all fairness, there's no reason to use toString - you could just compare the internal val:

public boolean equals(Object o) {
    if (this == o) {
        return true;
    }
    if (o == null) {
        return false;
    }
    if(getClass() != o.getClass()) {
        return false;
    }
    Int other = (Int) o;
    return val ==  other.val; // Here!
}
Mureinik
  • 297,002
  • 52
  • 306
  • 350
1

Everything is compiling and working, but I have no clue if my hashcode() function and equals() are good.

Your equals() should compare int val and not result of toString() of compared objects (this.val == other.val).

Your hashCode() looks good, though I would add @Override to it (same with equals()).

Furthermore i want to use create() to make objects like this: getInstance().create("1234");

Looking at its implementation, it looks fine (i.e. would work according to your needs):

public Int create(String s) {
    val = Integer.parseInt(s);
    return this;
}

though I don't think you really want to use it with getInstance(). Simply Int.create() would be enough:

public static Int create(String s) {
    val = Integer.parseInt(s);
    return new Int(val);
}

Note that you would need a private constructor.

Also, as someone noted in the comments, consider using generics instead of inheritance.

syntagma
  • 23,346
  • 16
  • 78
  • 134
0

First when you override Methods please do it with @Override Annotation. Then i would implement your equals method in another way. Just do return this.val == other.val instead of doing this.toString() == other.toString(). Your toString() method implementation is ok. Your hashCode is good as well. But please remove that create method. Use a constructor instead.

onCC
  • 71
  • 2
  • 10
  • Thanks I will add annotations. I need to make that create function, but dont really know how. Its part of my homework. Later I have to create ArrayList and create specific value type – Grzegorz Kunc Oct 16 '18 at 20:03
  • @GrzegorzKunc And what is the method supposed to do? – onCC Oct 16 '18 at 20:05
0

Can I implement equals() method using eq() like this ?

public boolean equals(Object o) {
    Value compare = (Value) o;
    return eq(compare);
}