Prevent abstract implementation from overriding certain method - java

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.

Related

Java method that can't be callable but can be overridden

If I don't want that a method on my class can be called, I just make it private.
But if I want to allow that method to be overridden, I have to make it protected
Is it possible to have a method on an abstract class that can't be called but can be overridden? (I guess not, but is there any workaround?)
Use case:
abstract class Super {
protected void finalize() {
}
public final void doThings() {
// do stuff
finalize();
}
}
and whoever wanted to extend the class:
class Sub extends Super {
#Override
protected void finalize() {
closeSockets();
alertSomeone();
}
}
But I don't want other classes calling mySub.finalize();
Instead of overwriting a method, the sub-class may provide the super-class with a Runnable which contains the code to be executed. You could do something like this:
public class Super {
private final Runnable subClassCode;
public Super(Runnable finalizeCode) {
subClassCode = finalizeCode;
}
public final void doThings() {
// do stuff
subClassCode.run();
}
}
public class Sub extends Super {
public Sub() {
super(() -> {
// code to be executed in doThings()
});
}
}
You dont need to set the Runnable instance in the constructor. You may also give access to a protected setFinalizeCode(Runnable) method but that method could also be called by other classes within the same package as Super.

Java: invoke a default method in another default method of the same interface

I'm very new to the java 8 features and try to understand default methods. Is there an easier way to invoke a default method by another default method of the same interface than using an anonymous class?
For example:
public class Frame{
public static void main(String... args){
Frame.C c= new Frame.C();
c.doSomething();
}
public interface A{
public default void doSomething(){
System.out.println("A");
}
}
public interface B extends A {
#Override
public default void doSomething(){
System.out.println("B");
//is there an easier way to invoke that method??
new B(){}.other();
}
default public void other(){
//doSomething();
System.out.println("other");
}
}
public static class C implements B{
#Override
public void other(){
Lambda.B.super.other();
System.out.println("C");
}
}
}
Your intention is not entirely clear, but the construct new B(){}.other(); implies two things:
You don’t want to invoke an overriding method implementation
The instance on which you invoke other() is obviously irrelevant when invoking it on an entirely different instance (new B(){}) is a viable solution
These two things together imply that you should use a static method instead:
public interface B extends A {
#Override
public default void doSomething(){
System.out.println("B");
otherInB();
}
default public void other(){
otherInB();
}
static void otherInB() {
//doSomething();
System.out.println("other");
}
}
Since your original method names did not carry useful information, it’s not possible to suggest a useful name for that static method either.
Note that Java 9 is going to introduce support for private methods in interfaces which allows hiding otherInB() to other classes and even making it non-static in case it has to use other methods on the same instance.
If the visibility of the method in Java 8 is an issue, consider that the actual place of a non-polymorphic method is irrelevant, so you can always use a companion class:
public interface B extends A {
#Override
public default void doSomething(){
System.out.println("B");
BHelper.other();
}
default public void other(){
BHelper.other();
}
}
…
/* not public */ class BHelper {
/* not public */ static void other() {
//doSomething();
System.out.println("other");
}
}
This even works if the implementation needs the actual B instance as you may pass it as a parameter.
public interface B extends A {
#Override
public default void doSomething(){
System.out.println("B");
BHelper.other(this);
}
default public void other(){
BHelper.other(this);
}
}
…
/* not public */ class BHelper {
/* not public */ static void other(B instance) {
//doSomething();
System.out.println("other");
}
}

implement an abstract method in derived class as static

I have these 2 classes
class A {
public void foo1() {
...;
foo2();
...;
}
protected abstract foo2();
}
class B extends A {
public foo2() {
......
}
I need foo2 to be static so I can do B.foo2() but I also want the functionality in class A to remain.n
Any suggestions?
}
You can't override static methods or implement abstract methods as static.
Static methods are defined on a class definition, not on a class instance. Abstract methods are defined on a class instance.
What you said doesn't make sense in fact.
Although I don't quite get why you need to do it, there is a workaround:
class B {
#Override
public void foo() {
fooUtil();
}
public static void fooUtil() {
// your impl here
}
}
Then you can do B.fooUtil() instead, and using its behavior to override A.foo().

Make sure method is executed, even if overriden

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
...
}

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