Make sure method is executed, even if overriden - java

Let's say I have an interface with some methods, like this:
interface Task {
void before();
void doStuff();
void after();
}
Here I would implement part of it:
abstract class PoliteTask implements Task{
#Override
public void before() {
System.out.println("Hey");
}
#Override
public abstract void doStuff();
#Override
public void after() {
System.out.println("Cya");
}
}
Now I want to make sure that those before() and after() implementations are called in all extending classes.
Here we have a class that needs to init something in before():
class ActualStuffTask extends PoliteTask {
private int fancyNumber;
#Override
public void before() {
// init some things
fancyNumber = 42;
}
#Override
public void doStuff() {
System.out.println("Look, a number: "+fancyNumber);
}
}
Obviously, ActualStuffTask overrides before(), hence it does not say "Hey", only "Cya".
If I made the methods in PoliteTask final, this wouldn't happen, but then it's child classes could not override the methods.
Calling super.before() in the ActualStuffTask would work, but I want to have this effect guaranteed, regardless of child class implementation.
The question is:
What pattern should I use to have both parent implementation, and child implementation?

I like to use abstract methods which you implement in the implementation classes.
abstract class PoliteTask implements Task{
#Override
public final void before() {
System.out.println("Hey");
doBefore();
}
protected abstract void doBefore();
protected abstract void doAfter();
#Override
public abstract void doStuff();
#Override
public final void after() {
System.out.println("Cya");
doAfter();
}
}
class ActualStuffTask extends PoliteTask {
private int fancyNumber;
#Override
protected void doBefore() {
// init some things
fancyNumber = 42;
}
#Override
public void doStuff() {
System.out.println("Look, a number: "+fancyNumber);
}
#Override
protected void doAfter() {
// something else
}
}
Notice that the Task methods are final. They don't need to be. It depends how you are building your API.

The usual approach for such case is like this (simplified example):
abstract class Base {
public final void before() {
System.out.println("Hey");
doBefore();
}
protected void doBefore() {
}
}
This way base code always will get executed, and subclasses can add their implementation.

You can follow the template method pattern. Create a final method in AbstractClass (say, doAll), that calls the other methods in order:
public final void doAll() {
before();
doStuff();
after();
}
Then you can have before and after also be final methods, so that they will always be executed by subclasses, and their behavior can't be changed.

One option is to call super.before() in your ActualStuffTask class explicitly:
#Override
public void before() {
super.before();
// init some things
fancyNumber = 42;
}
Another option is to change design of you parent class and "protect" before method with final keyword:
abstract class PoliteTask implements Task {
#Override
public final void before() {
System.out.println("Hey");
internalBefore();
}
protected abstract void internalBefore(); // child class should override this method
...
}

Related

How to create a java method on a base class that calls other methods?

I'm trying to build a base class with a method that needs to call a private method before and after performing the actual logic.
public abstract class Base {
public Base() {}
private void before() {
// doSomething
}
private void after() {
// doSomething
}
public void actual(Object object) {
before();
// doSomething
after();
}
}
public class SomeClass extends Base {
public SomeClass() {}
public void actual(Object object) {
// actual code that needs to be executed between before and after methods.
}
}
How would I go about this?
Create another method that can be overridden and implemented instead of overriding actual directly.
E.g.
public void actual(Object object) {
before();
doActual(object);
after();
}
protected abstract void doActual(Object object);
You could make the actual() method final if you want to ensure that nobody overrides it by mistake.
You can make the method as abstract e.g.
protected abstract void actual(Object object);
and create another public method which is going to be called
public void init(Object object){
before();
actual(object);
after();
}

How to force override method and call super at the same time

Ok, so recently I wanted to implement the following
public enum ObjectTypes {
STRING,
INTEGER
}
interface IObjectEnhancer{
void enhance(String s);
void enhance(Integer i);
ObjectTypes getLastEnhancedType();
}
class ObjectEnhancer implements IObjectEnhancer{
ObjectTypes lastUsedType=null;
#CallSuper
#Override
public void enhance(String s) {
this.lastUsedType=ObjectTypes.STRING;
}
#CallSuper
#Override
public void enhance(Integer i) {
this.lastUsedType=ObjectTypes.INTEGER;
}
#Override
final public ObjectTypes getLastEnhancedType() {
return lastUsedType;
}
}
class ObjectEnhancerChild extends ObjectEnhancer{
#Override
public void enhance(String s) {
super.enhance(s);
//child code
}
#Override
public void enhance(Integer i) {
super.enhance(i);
//child code
}
}
And for safety I wanted to add #CallSuper because I really want only the parent to remember the types but I also want the enhance(String) and enhance(Integer) to be abstract so that no clumsy future person (me included) forgets to actually implement these methods.
So below is a method to handle this sort of situation that apparently only I am having and the internet doesn't really have advice on, it might seem stupid to worry about such a small thing but if you have 10+ methods it stars becoming a nightmare(feedback and other solutions welcome):
Just make new abstract methods so that the child is forced to implement them and parent methods call the abstract methods instead of using #CallSuper:
abstract class ObjectEnhancer implements IObjectEnhancer{ //add abstract to parent
ObjectTypes lastUsedType=null;
abstract void enhance2(String s); //new
abstract void enhance2(Integer i); //new
//removed #CallSuper
#Override
final public void enhance(String s) { //changed to final
this.lastUsedType=ObjectTypes.String;
enhance2(s); //new
}
//removed #CallSuper
#Override
final public void enhance(Integer i) { //changed to final
this.lastUsedType=ObjectTypes.Integer;
enhance2(i); //new
}
#Override
final public ObjectTypes getLastEnhancedType() {
return lastUsedType;
}
}
class ObjectEnhancerChild extends ObjectEnhancer{
#Override
public void enhance2(String s) { //changed to abstract method
//removed super.enhance(s);
//code
}
#Override
public void enhance2(Integer i) { //changed to abstract method
//removed super.enhance(i);
//code
}
}

How to force classes to use a statement from an abstract method

I have an abstract method that implemented by other classes:
protected abstract void uninstallApp();
What I want to do is to force all the classes that must implement this method to use System.out.println() and another method: Log.report()
Is there any way that I can achieve this?
You could for example, do your logging stuff in the parent abstract class in a final method (so the child will not overwrite it). This class call a second method that the child classes should overwrite. Something like following:
protected final void uninstallApp(){
doUninstallApp();
Log.report();
}
protected abstract void doUninstallApp();
I agree with #Loic, we can go here for Command pattern...I tried to write the code below..May be It can help..
class Parent {
public final void uninstallApp() {
print();
doSomethingUsefull();
logReport();
}
//To be overriden as per requirement
protected void logReport() {
Log.report();
}
//To be overriden as per requirement
protected void print() {
System.out.println();
}
//To be overriden as per requirement
protected void doSomethingUsefull() {
//Implementation goes here
}
}
class Child extends Parent {
public void logReport() {
//Implementation goes here
}
public void print() {
//Implementation goes here
}
public void doSomethingUsefull() {
//Implementation goes here
}
}
class Main {
public static void main(String[] args) {
Parent p = new Child();
p.uninstallApp();
}
}

Prevent abstract implementation from overriding certain method

I have an interface called Worker which I want to expose so that the end-user can simply call:
Worker w = WorkerFactory.createInstance();
w.mainBit();
How can I prevent classes which extend my AbstractWorker class from providing their own implementation of the mainBit method?
This is the structure I have so far:
interface Worker {
void mainBit();
}
class WorkerFactory {
public static Worker createInstance() {
return new WorkerImpl();
}
}
abstract class AbstractWorker implements Worker {
#Override
public void mainBit() {
this.doThing1();
this.doThing2();
}
public abstract void doThing1();
public abstract void doThing2();
}
class WorkerImpl extends AbstractWorker {
#Override
public void doThing1() {
}
#Override
public void doThing2() {
}
#Override
public void mainBit() {
// I don't want classes to override this functionality
}
}
You can do that by making the method final.
Use the final keyword.
public final void mainbit ()
...
Mark the method as final, which prevents overriding:
public final void mainBit()
If you want to always use the AbstractWorker's mainBit, make it final in this class. This way, the subclasses won't override it.
Mark it final inside you abstract class (in Java). No other subclass will be allowed to override it.

Overwriting methods: how to "inject" into the super-method?

Assuming three classes, one being a subclass of the other. Each overwrite the parents' method.
public class BaseClass {
public void doStuff() {
performBaseTasks();
}
}
public class MiddleClass extends BaseClass {
// {BaseClass} Overrides
public void doStuff() {
performMiddleTasks();
super.doStuff();
}
}
public class FinalClass extends MiddleClass {
// {BaseClass} Overrides
public void doStuff() {
performFinalTasks();
super.doStuff();
}
}
When calling new FinalClass().doStuff(), this would lead to a method
invokation order as follows:
performFinalTasks();
performMiddleTasks();
performBaseTasks();
I want to bring the perfomFinalTasks() between performMiddleTasks() and
performBaseTasks(). How can I do this?
performMiddleTasks();
performFinalTasks();
performBaseTasks();
Write a public method in final class doStuffDifferently() and invoke these methods in that order. I am not sure it's possible to do it via any other tricks in the doStuff() method.
One possible way, if you can make the middle class abstract:
public abstract class MiddleClass extends BaseClass {
// {BaseClass} Overrides
public void doStuff() {
performMiddleTasks();
doProxyExec();
super.doStuff();
}
public abstract void doProxyExec();
}
You override the proxy method in your subclass:
public class FinalClass extends MiddleClass {
// {BaseClass} Overrides
public void doStuff() {
super.doStuff();
}
// {MiddleClass} Overrides
public void doProxyExec(
performFinalTasks();
}
}
A not very polymorphic way of method call chaining, but then again the original design is kind of ... odd.

Categories