简体   繁体   中英

Write a method implementation in base class which requires override in subclasses?

In Java...

I am creating a class Foo which contains a method doAction(). My requirements:

  1. doAction() must have a default implementation (ie function body) in Foo.
  2. All subclasses of Foo must override doAction(), meaning that subclasses will get a compiler error if they do not provide a new implementation.
  3. I need to be able to instantiate Foo.

abstract would work, except that it does not allow me specify a function body for doAction().

Edit

It is impossible to simultaneously satisfy all of the requirements, end of story. You must give up at least one condition, and probably consider an entirely different approach to the problem you're trying to solve.


Use two separate methods. Either:

abstract class Foo {

    // Override this method
    abstract void doActionInSubclass();

    // You can't override a final method
    // And you don't want subclases to override this one
    final void doAction () {
        // do whatever default-y things you want here
        doActionInSubclass();
    }
}

Or just make the "required" method completely separate from the one you want to force subclasses to override:

abstract class Foo {
    abstract void mustOverrideThisInConcreteSubclasses();

    final void doAction() {
        // default-y things here
    }
}

If you give a default implementation to a method in Java, you can't force the subclasses to override it again. If you can, use a template method pattern using a different method name:

public class Foo{

    public abstract void templateMethod();
    public final void doAction(){

    //default implementation

     templateMethod(); // call template method
    }
}

Implement your method in Foo and make it always throw an exception, like UnsupportedOperationException . This will require the subclasses to override the method.

If all subclasses should override it why do you want to provide a default implementation?! it would be pointless since no one would use it. However you probably have some code of your doAction you want to be executed by any subclasses and some code you want to be overridden. In this case you might design as follow:

doAction(){
     //put your default code here...
     specificAction();
}

abstract specificAction();

In this way doAction has its own implementation which is ended by a specificAction invocation which should instead be implemented by subclasses

In the constructor(s) of class Foo you could use reflection :

class Foo {
    public Foo() {
        Class c = getClass();
        if (!c.equals(Foo.class))
        {
            // try/catch omitted for brevity
            Method m = c.getMethod("methodName", new Class[0]);
            if (m.getDeclaringClass().equals(Foo.class))
            {
                throw new Exception("blah blah blah");
            }
        }
    }
}

This won't produce a compile-time error, but since the call to super() in a constructor can't be wrapped with try there's no way for anyone making a subclass to get around it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM