How to force implementation of a method in subclass without using abstract?

28,996

Solution 1

You can not force a subclass to override a method. You can only force it to implement a method by making it abstract.

So if you can not make myMotherClass abstract you can only introduce another superclass that extends myMotherClass and delegates to the method that must be implemented:

public abstract class EnforceImplementation extends myMotherClass {

        public final void myMethod(){
             implementMyMethod();
        }

        public abstract void implementMyMethod();
}

EDIT

I found another interessting way of solving the problem in the hemcrest api that is e.g. used by mockito.

public interface Matcher<T> extends SelfDescribing {

    /**
     * Evaluates the matcher for argument <var>item</var>.
     * <p/>
     * This method matches against Object, instead of the generic type T. This is
     * because the caller of the Matcher does not know at runtime what the type is
     * (because of type erasure with Java generics). It is down to the implementations
     * to check the correct type. 
     *
     * @param item the object against which the matcher is evaluated.
     * @return <code>true</code> if <var>item</var> matches, otherwise <code>false</code>.
     *
     * @see BaseMatcher
     */
    boolean matches(Object item);

    /**
     * This method simply acts a friendly reminder not to implement Matcher directly and
     * instead extend BaseMatcher. It's easy to ignore JavaDoc, but a bit harder to ignore
     * compile errors .
     *
     * @see Matcher for reasons why.
     * @see BaseMatcher
     */
    void _dont_implement_Matcher___instead_extend_BaseMatcher_();
}

The interface specifies a method _dont_implement_Matcher___instead_extend_BaseMatcher_. Of course it does not prevent others from implementing the Matcher interface, but it guides the developer in the right direction.

And the BaseMatcher class implements the _dont_implement_Matcher___instead_extend_BaseMatcher_ method as final

public final void _dont_implement_Matcher___instead_extend_BaseMatcher_() {
    // See Matcher interface for an explanation of this method.
}

Finally I think that this is a design problem, because the BaseMatcher obviouosly implements logic that every Matcher should implement. Thus it would have been better to make the Matcher an abstract class and use a template method.

But I guess they did it because it was the best compromise between bytecode compatibility and new features.

Solution 2

You could rework your hierarchy so that your concrete classes are only leafs of the tree.

Instead of

myClass extends myMotherClass

Consider

myClass extends myMotherAbstractClass
myMotherClass extends myMotherAbstractClass 

This way the Abstract class is inherited by both instantiated classes. It is likely in this case the myMotherClass would be extremely thin, just the implementation of myMethod.

Solution 3

One thing most people are overlooking is the following implementation (although I saw mention of it in a comment):

public class MyMotherClass { 

    public void myMethod() {
      throw new RuntimeException("Method not overwritten");
    }    

}

In most cases this should be enough, as you should have some form of acceptance testing (even if it is only testing the inheriting class by hand). In theory, you are still introducing the possibility that nobody will realize that the method hasn't been overwitten until production though.

Share:
28,996

Related videos on Youtube

Maniz
Author by

Maniz

Updated on July 09, 2022

Comments

  • Maniz
    Maniz almost 2 years

    I want to force subclass to implement an implemented method of my mother class. I look this Java - Force implementation of an implemented method but i can't convert my mother class to an abstract class.

    public class myMotherClass { 
    
       myMethod {
    
          ...some code ..
    
       }
    
    }
    
    public class myClass extends myMotherClass {
    
       myMethod {
    
          ... other code ...
       }
    
    }
    

    So, in this exemple, I want to force myClass implement myMethod.

    Sorry for my english...

    • André Stannek
      André Stannek over 10 years
      In short: You can't without making it abstract
    • Kevin Bowersox
      Kevin Bowersox over 10 years
      @stonedsquirrel What about an interface?
    • Maniz
      Maniz over 10 years
      This is not possible using annotations or by throwing an exception if the class don't implement the method?
    • André Stannek
      André Stannek over 10 years
      @KevinBowersox Of course there are ways to create such a behaviour by changig the design. All I'm saying is forcing to override a non abstract method from a superclass is not possible. An interface wouldn't help either as the superclass would also implement it. This way the subclass again would not be forced to implement the method.
  • Daniel Methner
    Daniel Methner about 2 years
    also this only works as long as you dont need the implementation of the parent class.