Provide implementation for abstract method but restrict visibility - java

I have a method in an abstract class that calls an abstract method, for which the subclasses must provide the implementation.
public abstract class AClass {
public void foo() {
...
fooToImplement();
...
}
// DON'T CALL THIS METHOD, ONLY PROVIDE IMPLEMENTATION!
protected abstract void fooToImplement();
}
I want to make sure that the subclasses don't call fooToImplement(), they should always use foo() instead. The behavior is something like a "private abstract" method, but that's not possible in Java.
Is there some alternative? Thanks!

If you don't want your subclasses to be able to call this method you could use strategy: Extract the behavior of the method into an interface and pass an implementation of this interface to the object. E.g.
IStrategy {
public void fooToImplement();
}
AClass {
public AClass(IStrategy impl) {...}
public void foo() {
...
strategy.fooToImplement();
...
}
}
Delegation instead of inheritance. In java 8 this would be a little bit easier.
If your implementation of IStrategy would need access to the data of the object AClass, you could try to implement it as an inner class.

The method has to be visible by your subclass if you want it to be overriden.
You have to use a class witch does not extends AClass as caller.
public class BClass extends ACLass {
#Override
protected void fooToImplement() {
System.out.println("override me im famous");
}
}
public class CClass {
private BCLass bInstance;
public void doSomething(){
bInstance.foo();
// !!! NO ACCESS TO fooImplement()
}
}

Since fooToImplement() needs to be visible to subclasses to be implemented there and there's no way to distinguish between "implement visibility" and "execution rights", you can't do this by inheritance.
You could however combine your object with another object that contains fooToImplement() by composition:
interface FooImplementation {
void fooToImplement(AClass a);
}
public abstract class AClass {
private final FooImplementation fooImpl;
protected AClass(FooImplementation fooImpl) {
this.fooImpl = fooImpl;
}
public void foo() {
...
fooImpl.fooToImplement(this);
...
}
}
That wouldn't prevent anyone from outside the class from using yourFooImpl.fooToImplement(yourAClass) however. To prevent this you could create a class that provides the information that fooToImplement() needs, but that can only be instanciated from within AClass:
interface FooImplementation {
void fooToImplement(AClass.AClassFooView a);
}
public abstract class AClass {
private final FooImplementation fooImpl;
protected AClass(FooImplementation fooImpl) {
this.fooImpl = fooImpl;
}
public class AClassFooView {
...
private AClassFooView() {
}
}
public void foo() {
...
fooImpl.fooToImplement(this.new AClassFooView());
...
}
}
But fooToImplement could pass the reference to AClassFooView to other classes...
However depending on the implementors of your class making absolutely sure in the documentation, that nobody should call fooToImplement() could also be an alternative.
Ultimately you have to trust the implementors, since there's also the the possibility of someone using reflection to get access to private members, reverse engeneering+changing+recompiling your class ect..

You can use AOP to this, for example add aspect #Before to fooToImplement() and check stacktrace of calling and throw IllegalArgumentException if fooToImplement() be called any method except foo(), something like:
if(!Thread.currentThread().getStackTrace()[1].getMethodName().equals("foo")) {
throw new IllegalArgumentException("You musn't call fooToImplement() directly"+
", using foo() instead");
}
However this way has two problem:
perfomance
runtime exception

Related

Java subclass implementation mandatory constructor

Is there any way in Java to enforce a subclass or interface implementation to have a constructor with a given signature?
Let's say that I´ve got either:
public interface MyInterface {
// any methods
}
or
public abstract class MyBaseClass {
// any abstract methods
}
Now, is it possible to do anything to require
public class MySubClass extends MyBaseClass {
public MySubClass(String s) { }
}
or
public class MySubClass implements MyInterface {
public MySubClass(String s) { }
}
to always have a constructor that takes a String as it´s only input parameter?
The obvious workaround is to create a factory interface with a method taking a String and inject it where required. Which is not what I would like to do.
Not really, the closest I think you can get is something like:
abstract class B {
public B(String s) {
}
}
public class A extends B {
public A(String s) {
super(s);
}
}
This forces A to implement a non default constructor which must call super(String) but can not prevent the following:
public class A extends B {
public A() {
super("");
}
}
There have been many times where I wished something like this existed, but sadly it doesn't. Even something like what David Soroko suggested wouldn't work because a subclass still wouldn't be forced to have a String constructor - it can just pass any String it likes to super. Simply put, there is no such thing within the Java syntax itself.
I suppose the closest one could get to such a capability is if someone built an annotation processor that allows you to use an annotation like #MustHaveUnaryConstructor(String.class) and then if any subclass does not have such a constructor, it causes compilation to fail and tells you which subclass broke the contract. But I haven't found such a thing and I don't know enough about annotation processing to build one myself. So TL;DR, no, you can't.

How to force a subClass to implement a method in superClass which has body

Class Base{
public void doThings(){
//some logic that needed by subclass
}
}
Class A extends Base{
public void doThings(){
super.doThings();
doOtherThings();
}
}
What I want is to force A to overwrite doThings() method(there will be error message if not) and call super.doThings(); but doThings() in Base should not be abstract for it has body.
Is there any decent solutions? I found the same question in below link but the accepted answer does not answer it right.
Force SubClasses to #Override method from SuperClass. Method in SuperClass must have body
If you want to make sure that doThings of the base class is called, you should design your class like this:
abstract class Base {
public void doThings() {
// do some things here
...
// make sure subclass does some things too
methodYouMustImplement();
}
abstract void methodYouMustImplement();
}
class A extends Base {
#Override void methodYouMustImplement() {
// do some other things
}
}
This way, A is forced to give a implementation of methodYouMustImplement() and it is guaranteed by design that your code in doThings() is called without the need to remember to call super.doThings().
You could then consider making doThings() final, as Andy Turner suggested.
I think it would be easier to use a construct such as:
public class Base {
public void doStuff() {
doSpecificStuff();
// do base stuff every one has to do
}
abstract void doSpecificStuff();
}
public class WeirdlySpecific extends Base {
public void doSpecificStuff() {
// specific stuff happens
}
}
This does not force WeirdlySpecific to actually implement the doStuff() method, but as long as doStuff() is called as a contract by any caller, each more specific implementation has its own version of events.
A requirement to call the super method is considered an anti-pattern; that aside, the only way you can force a subclass to implement a method is to make it abstract.
If you want super.doThings() to be called first, and then subclass-specific stuff to be run after, turn the problem around:
Make doThings() final
Add an abstract method that is called within doThings().
Something like this:
abstract class Base {
public final void doThings() {
methodYouMustImplement();
// Stuff after subclass-specific implementation.
}
abstract void methodYouMustImplement();
}
class A extends Base {
#Override void methodYouMustImplement() {
doOtherThings();
}
}
The fact that doThings() is final is important to the requirements: this guarantees that the things you want to happen when doThings() is invoked, because no subclass can change this method. If you leave it non-final, subclasses can decide to override doThings(), meaning that methodYouMustImplement() (and any other actions you specify in doThing()) are not necessarily called.

Partial implementation of an abstract method?

For example, I have many classes that all need a certain method.
In this method, all these classes need one line of code, the remainder of the method is different.
How could I achieve something like this:
void method(){
everybodyDoesThisStuff;
// more individual stuff
// more individual stuff
}
Abstract methods cannot have a body, and if you were not to make it abstract you would then override the method and lose it.
You should make the method that does the "more individual stuff" abstract, not the method itself.
// AbstractBase.java
public abstract class AbstractBase {
public final void method() {
everybodyDoesThisStuff();
doIndividualStuff();
}
abstract void doIndividualStuff();
private void everybodyDoesThisStuff() {
// stuff that everybody does
}
}
// ConcreteClass.java
public class ConcreteClass extends AbstractBase {
void doIndividualStuff() {
// do my individual stuff
}
}
One solution is to require all subclasses to call super.method(). The problem is that there's no way to actually enforce that. Another option is to create a separate method that internally executes the required line and then calls an abstract method:
public final void method() {
callEveryTime();
doMethod();
}
protected abstract void doMethod();
Note that method() is public final so it can be called anywhere but not overridden, whereas doMethod() is protected so it can be overridden but not called outside its package (or subclasses).
You can make a normal method call an abstract method:
void foo(){
// do stuff
bar(); // let the abstract method do the rest
}
abstract void bar();
If you're asking yourself whether you need partial implementations of an abstract method, it's usually time to reconsider the granularity of your design.
Why not extract everybodyDoesThisStuff into a separate method and put it in an Interface?

Define and execute partial functions of an interface

I am new to Java so i have some obvious (to some of you) questions about declaration, definition and execution of some functions.
Suppose you have declared two methods in an interface and you want to define the behavior of the first function in a (abstract?) class and the second function in another (abstract?) class.
Is there a way to define two methods in two separate classes? For example i could have a lot of methods in an interface but I want to implement just one of them because a specific object does not needs the others. How can I do that??
Java Code example :
interface DeclareFcnts {
void foo1();
void foo2();
}
abstract class Define_fcn1 implements DeclareFcnts {
public void foo1() {
// TODO Auto-generated method stub
}
}
abstract class Define_fcn2 implements DeclareFcnts {
public void foo2() {
// TODO Auto-generated method stub
}
}
class Myclass {
public static void main(String args[]) {
// How can i create an object that reference to the first function only?
}
}
If you implement an interface in a class, you must assume it will have all the interface methods declared. You must define what happens if any of these methods are invoked. Consider this:
DeclareFcnts instance = new Define_fcn1();
instance.foo2(); // what happens here?
What is your expected behavior on the second line? It could throw an exception, do nothing, (or return a value if the method wasn't void).
One option is to define the behavior in the concrete implementing class (because you cannot instantiate abstract classes), which is what you would like to avoid. Fortunatelly, in Java 8, there is another way - using default methods:
interface DeclareFcnts {
default void foo1() { /* default implementation, e.g. throw or do nothing */ }
default void foo2() { /* default implementation, e.g. throw or do nothing */ }
}
class Define_fcn1 implements DeclareFcnts {
public void foo1() { /* do something */ }
}
In this case, Define_fcn1 will inherit implementation of foo2 from DeclareFcnts much like if it inherited from a super class. You can notice that the class no longer needs to be abstract.
That said, you should try to avoid such situations. They will make unit testing, refactoring, etc., more difficult. You may possibly split your interface into multiple interfaces. If you need both methods somewhere, you can pass the interfaces separately, or, if absolutely necessary, define another interface like this:
interface Foo1Iface { void foo1(); }
interface Foo2Iface { void foo2(); }
interface BothIface extends Foo1Iface, Foo2Iface { }
I would avoid it if possible, though. You may get more suggestions if you add more details to your answer.
AFAIK it is not possible, when you are implementing an interface you are obliged to #override those methods in that interface but you can leave it as blank assuming that you would not call it. Although:
This is your Generic interface, it can be anything as long as you meet the requirements.
Credits to Pinterest.
If you are going to design a house it does not make sense to add a wheel or anything unrelated to the house. Otherwise create a separate Interface for a Car or a Bus.
An Example of Bad Design
interface GenericInterface{
public void defineDoor();
public void defineWindow();
public void defineWheel();
}
The actual implementation
class House implements GenericInterface{
#Override
public void defineDoor{
// do something
}
#Override
public void defineWindow{
// do something
}
#Override
public void defineWheel{
// does not make sense to the House.
}
}
Here is another class that implements the Generic Interface
class Car implements GenericInterface{
#Override
public void defineDoor{
// do something
}
#Override
public void defineWindow{
// do something
}
#Override
public void defineWheel{
// do something.
}
}
Though our Car fits the above Interface but since when did the House contains a wheel?. The right way to do this is to create Separate Interface for Car and House.
You can not do this!
you must declare body for your method that declared in interface and then create instance of class
or you can use java 8 default declaration for your interface methods
for example:
public interface IX
{
void sayHello();
void sayBye();
default void showInfo()
{
System.out.println("you call show Info method");
}
}

How to do in java what in C++ is changing an overridden method visibility?

In C++ it's possible to change an overridden method's visibility. I find this feature very useful sometimes, for example:
consider you want a class to have some debugging methods, but you don't want them to be visible as public class interface. You could have something like:
class IDebuggable {
public:
virtual void debug(std::string s) = 0;
};
class MyProductionClass: public IDebuggable
public:
void myClassMethod() {}
private:
virtual void debug(std::string) {
// do some debug here
}
};
To do so, when using an object of class MyProductionClass, all I can access is MyProductionClass::myClassMethod() (the production interface).
However, if I want to use it's debugging features, I can do this:
MyProductionClass* obj = new MyProductionClass();
IDebuggable* iface = obj;
iface->debug("Hello World");
I've found in my experience this "feature" quite useful.
In java this is not possible as it's forbidden to change the visibility of an inherited method.
Is there another way I can achieve the above artifact?
Thanks a lot
You cannot reduce visibility of inherited method. This is right. However you can create as many interfaces as you want and make you class to implement these interfaces. Then if your client works with specific interface it "does not have access" to other even public methods.
Here is an example.
public interface Foo {
public void foo();
}
public interface Bar {
public void bar();
}
public class MyClass implements Foo, Bar {
public void foo() {}
public void bar() {}
}
Here is how we use this class:
Foo f = new MyClass();
You can call foo() here and cannot call bsar(). You can however cast Foo to Bar and then use bar() method.
Personally, I hate when people change method visibility this way. I think it's much better to preserver the visibility and expose interfaces, but not the classes themselves, for external users.
Like:
class MyInterface {...}
class MyDebugable {...}
class MyClass : MyInterface, MyDebugable {...}
Give MyInterface to the users and user MyClass internally.
By changing visibility you violate Liskov substitution principle. At the same time your users still can cast to IDebuggable and call your 'private' methods
In Java you can increase method visibility but you can't reduce it when subclassing. This is due to the fact that you may access object via parent class (interface) and all methods defined in parent class should be available to caller.
So the following is possible:
class A {
protected void foo() {}
}
class B extends A {
#Override
public void foo() {}
}
This is (for God's sake) not possible in Java. Furthermore, what you want could be much better achieved by using a logging framework with different configurations for development/production.
Implement a feature discovery like this:
class A {
public final T <T> lookup(Class<T> klazz) {
return map.get(klazz);
}
public A() {
map.put(IDebugable.class, new IDebuggable() { ... };
}
}
A a = ...;
a.lookup(IDebuggable.class).debug();

Categories