Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can an abstract class force a concrete method to be overridden?

I use a library where an abstract class overrides a concrete method inherited from Object with an abstract method:

public abstract class A {
    @Override
    public abstract boolean equals(Object obj);
}

To extend this class, I have to implement the equals method:

public class B extends A {
    @Override
    public boolean equals(Object obj) {
        return obj != null && obj.getClass() == B.class;
    }
}

Why can an abstract method (A::equals) override a concrete method (Object::equals)? I don't see the goal of this.

like image 596
gontard Avatar asked Jun 17 '15 07:06

gontard


People also ask

Can we override concrete method of abstract class?

Can subclasses override concrete methods from an abstract superclass. Yes they can override them.

Can abstract class have any concrete method?

No. Abstract class can have both an abstract as well as concrete methods. A concrete class can only have concrete methods. Even a single abstract method makes the class abstract.

Which method must be override concrete class?

The concrete method definition in the abstract class provides a default implementation that is generally acceptable by many child class implementations but can also be overridden in case a different implementation is required. But the abstract method must always be overridden by all the child classes.

Can abstract can be overridden?

Abstract methods cannot be overridden by a concrete subclass.


1 Answers

In this specific example it makes perfect sense. If sub-classes of A are meant to be used in Collections, where equals is widely used to locate objects, making A's equals method abstract forces you to give non-default implementation of equals in any sub-classes of A (instead of using the default implementation of the Object class which only compares instance references).

Of course, your suggested implementation of equals in B makes little sense. You should be comparing the properties of the 2 B instances to determine if they are equal.

This is a more suitable implementation :

public class B extends A {
    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof B))
            return false;
        B other = (B) obj;
        return this.someProperty.equals(other.someProperty) && this.secondProperty.equals(other.secondProperty);
    }
}

In addition, remember to override hashCode whenever you override equals (since the contract of equals and hashCode requires that if a.equals(b) == true then a.hashCode() == b.hashCode()).

like image 62
Eran Avatar answered Oct 25 '22 01:10

Eran