How to make this Java Interface flexible - java

I have this Java Interface:
public interface Box {
public void open();
public void close();
}
This interface is extended by this class:
public class RedBox implements Box {
public void open() {
}
public void close() {
}
}
The problems is that I'm looking to add other classes in the future that will also implement the Box Interface. Those new classes will have their own methods, for example one of the classes will have a putInBox() method, But if I add the putInBox() method to the Box Interface, I will also be forced to add an empty implementation of putInBox() method to the previous classes that implemented the Box Interface like the RedBox class above.
I'm adding putInBox() to the Box Interface because there is a class Caller that takes an object of classes that implemented the Box Interface, example:
public class Caller {
private Box box;
private int command;
public Caller(Box b) {
this.box = b;
}
public void setCommandID(int id) {
this.command = id;
}
public void call() {
if(command == 1) {
box.open();
}
if(command == 2) {
box.close();
}
// more commands here...
}
}
Caller c = new Caller(new RedBox());
c.call();
How do I implement the Box Interface in the new classes without been forced to add empty implementation of new methods to each of the previous classes that implemented the Box Interface.

You are not limited to a single interface - you can build an entire hierarchy! For example, you can make these three interfaces:
public interface Box {
public void open();
public void close();
}
public interface LockableBox extends Box {
public void lock();
public void unlock();
}
public interface MutableBox extends Box {
public void putItem(int item);
public void removeItem(int item);
}
Now your boxes can implement an interface from the hierarchy that fits your design.
public class RedBox implements LockableBox {
public void open() {}
public void close() {}
public void lock() {}
public void unlock() {}
}
public class BlueBox implements MutableBox {
public void open() {}
public void close() {}
public void putItem(int item) {}
public void removeItem(int item) {}
}
With a hierarchy in place, you can continue programming to the interface:
MutableBox mb = new BlueBox();
mb.putItem(123);
LockableBox lb = new RedBox();
lb.unlock();

The new classes implementing the Box interface will only need to implement the methods in the Box interface, not any other methods in other classes implementing the Box interface.

As said above, there's no need to have a new method in a new class added to the Box interface itself, you can just leave it in that new class, and so it won't interfere with any other implementation.
But if you do want to have new methods at the interface level, a way to introduce some flexibility is to use an (abstract) base implementation of your interface that provides (empty) implementations of all methods:
public abstract class BoxBase implements Box {
public void open() { }
public void close() { }
}
public class RedBox extends BoxBase {
#Override
public void open() {
// open a red box
}
}
This way, when adding new methods to your Box interface, you will only need to add an implementation of the method to the BoxBase class, and it won't interfere with your RedBox class.

Related

Alternate design for multiple inheritance

My program takes data from different file types and inserts them into different DBs depending on the department which uploaded the file.
To accomplish this, I have a base abstract class AbstractHandler which has some methods which are unimplemented and some which are common to all children. Two types of abstract classes extend from this class, InputTypeAHandler, InputTypeBHandler, etc. and OutputTypeAHandler, OutputTypeBHandler, etc. These abstract classes also implement some more methods but not all.
I have concrete classes which I want to extend from these two types of classes and which will implement some more methods specific to every class. For example,
abstract class AbstractHandler {
public void method1() {
// ....
}
public abstract void method2();
public abstract void method3();
public abstract void method4();
}
abstract class InputTypeAHandler extends AbstractHandler {
#Override
public void method2() {
// ....
}
}
abstract class OutputTypeBHandler extends AbstractHandler {
#Override
public void method3() {
// ....
}
}
public class ConcreteHandler1 extends InputTypeAHandler, OutputTypeBHandler {
#Override
public void method4() {
// ....
}
}
public class ConcreteHandler2 extends InputTypeCHandler, OutputTypeAHandler {
#Override
public void method4() {
// ....
}
}
Since Java does not allow multiple inheritance, how do I do this?
You seem to implement some kind of conversion between any pair of A,B,C... types (perhaps formats?). If it is the case, the AbstractHandler probably has multiple responsibilities. Split its logic to part involving source format and part involving target format. You can inspire in converter pattern or GoF Bridge pattern.
I use lombok and the power of interfaces for this:
public class Test implements InputTypeAHandler,OutputTypeAHandler {
#Delegate
OutputTypeAHandlerImp outputTypeAHandlerImp = new OutputTypeAHandlerImp() {
#Override
String id() {
return "mellow";
}
};
#Delegate
InputTypeAHandlerImp inputTypeAHandler = new InputTypeAHandlerImp(){
#Override
String id() {
return "hello124";
}
};
}
public static abstract class OutputTypeAHandlerImp implements OutputTypeAHandler {
abstract String id();
#Override
public void write(String s) {
System.out.println(s);
}
}
public static abstract class InputTypeAHandlerImp implements InputTypeAHandler {
abstract String id();
#Override
public String read() {
return new Scanner(System.in).nextLine();
}
}
public interface InputTypeAHandler {
String read();
}
public interface OutputTypeAHandler{
void write(String s);
}

Dynamically cast classes

I'm trying to do something along the lines:
abstract class Base {}
public interface One {...}
public interface Two {...}
public class A extends Base implements One {...}
public class B extends Base implements One, Two {...}
public class C extends Base implements Two {...}
public class Container
{
class Handler
{
public void doSomething(A obj){System.out.println("A");}
public void doSomething(B obj){System.out.printLn("B");}
public void doSomething(C obj){System.out.println("C");}
}
Base base;
Handler handler;
public Container(Base base)
{
this.base = base;
this.handler=new Handler();
}
public void set(Base base)
{
this.base=base;
}
public void go()
{
this.handler.doSomething(this.base);
}
}
Container con=new Container(new A());
con.go();
con.set(new B());
con.go();
Where the output would end up being "A" "B", but I'm running into problems dynamically casting Container.base to the appropriate class;
The closest solution I have found is in the Container.go function add in an if else chain checking the instanceOf the class and casting the parameter to the corresponding class then calling handler.doSomething in each if block.
public void go()
{
if(this.base instanceOf A)
{
this.handler.doSomething((A)this.base);
}
else if(this.base instanceOf B)
....
}
Is there a better way to go about this?
Which method is called is determined at compile time and not at run time so dynamic casting isn't going to work without some reflection or other tinkering about. I would suggest a better approach is to move the logic for
public void doSomething(A obj){System.out.println("A");}
public void doSomething(B obj){System.out.printLn("B");}
public void doSomething(C obj){System.out.println("C");}
Into the the specific classes. For example:
abstract class Base {
absract public void doSomething();
}
public class A extends Base implements One {
public void doSomething() {System.out.printLn("A");}
}
...
class Handler {
public void doSomething(Base obj){obj.doSomething();}
}
Now your handler doesn't need to care about the specific class of a Base object it is getting.
You could use the visitor pattern:
public interface Visitor {
public void doSomething(A obj);
public void doSomething(B obj);
public void doSomething(C obj);
}
Declare an abstract method in Base (or in a new interface):
abstract class Base {
public abstract void accept(Visitor v);
}
and implement it in A, B, C:
public class A extends Base implements One {
#Override
public void accept(Visitor v) {
v.doSomething(this);
}
...
}
public class B extends Base implements One, Two {
#Override
public void accept(Visitor v) {
v.doSomething(this);
}
...
}
public class C extends Base implements Two {
#Override
public void accept(Visitor v) {
v.doSomething(this);
}
...
}
Handler implements Visitor:
class Handler implements Visitor {
#Override
public void doSomething(A obj){
System.out.println("A");
}
#Override
public void doSomething(B obj){
System.out.printLn("B");
}
#Override
public void doSomething(C obj){
System.out.println("C");
}
}
And finally, go becomes:
public void go() {
this.base.visit(this.handler);
}
UPDATE
Note that #Evan Jones' solution is simpler and it could be what you need. The visitor pattern is used when you want to separate the implementations of the doSomething methods from the A, B, C classes and/or you want the ability to add new operations without changing these classes.

How to use Java Generics to enforce type restrictions

This question is a bit advanced so naturally also a little complicated. I will try and do my best to be as clear as possible.
As the title reads, I'd like to use Java Generics to enforce type restrictions when constructing an objects from some top level (main).
I have never really used Java generics but I found a pretty good use case for it which I am not sure how to implement.
I'd like to enforce type restriction when composing an object. Let me try to clarify with an example:
I have a top level main method here where I am evoking a NumberEngine object where I initialize and call methods of it. Notice when I call setExecuteBehavior(), I pass it an object of type RunNumberEvaluation (which along with RunStringEvaluation implements an interface called ExecutionBehavior).
As the name implies, NumberEngine works only with Numbers and not Strings, so it's inappropriate for me to pass setExecuteBehavior() an object of type RunStringEvaluation. How can I enforce this behavior at compile time?
public static void main(String[] args) {
NumberEngine numberEngine = new NumberEngine();
numberEngine.init("/path/to/forms");
numberEngine.getEngineVesion();
numberEngine.setExecuteBehavior(new RunNumberEvaluation);
numberEngine.performExecution();
// Here this should not compile, essentially throw me a compile error saying it can only accept
// an object of type RunNumberEvaluation, sincle NumberEngine can only run
// objects of type RunNumberEvaluation, etc...
numberEngine.setExecuteBehavior(new RunStringEvaluation());
numberEngine.performExecution();
}
So here I would like to basically make NumberEngine's setExecuteBehavior to only accept behavior which is relevent to it like the processing of data which pertains to numbers and not Strings. And vice-versa for StringEngine. I want StringEngine to only accept objects which pertains to Strings and not Numbers.
How can I accomplish this with Java generics?
I was thinking about something like this...
NumberEngine<? extends Numbers> extends Engine
Not even sure if this makes sense...
I have included working code below as an illustration of what I'm attempting to communicate.
I have an object of type Engine which is an abstract class with many extending concrete classes such as StringEngine, NumberEngine, et cetera. I have decoupled the algorithmic functionality into an interface with classes that implement that interface.
Base Abstract Class
public abstract class Engine {
ExecuteBehavior executeBehavior;
public void setExecuteBehavior(ExecuteBehavior executeBehavior) {
this.executeBehavior = executeBehavior;
}
public void performExecution() {
executeBehavior.execute();
}
public abstract void init(String pathToResources);
}
Concrete Implementing Class 1
public class StringEngine extends Engine {
public StringEngine() {
executeBehavior = new RunNumberEvaluation();
}
#Override
public void init(String pathToResources) {
System.out.println("Initializing StringEngine with resources "+pathToResources);
System.out.println("Successfully initialized StringEngine!");
}
}
Concrete Implementing Class 2
public class NumberEngine extends Engine {
public NumberEngine() {
executeBehavior = new RunStringEvaluation();
}
#Override
public void init(String pathToResources) {
System.out.println("Initializing NumberEngine with resources "+pathToResources);
System.out.println("Successfully initialized NumberEngine!");
}
}
Algorithm Interface
public interface ExecuteBehavior {
void execute();
}
Algorithm Implementation 1
public class RunNumberEvaluation implements ExecuteBehavior {
#Override
public void execute() {
// some processing
System.out.println("Running numeric evaluation");
}
}
Algorithm Implementation 2
public class RunStringEvaluation implements ExecuteBehavior {
#Override
public void execute() {
// some processing
System.out.println("Running string evaluation");
}
}
If you haven't noticed but here I'm making use of the strategy pattern where I segregate the varying algorithms into a family via interface from the static non-changing code.
Edit: I'd like to maintain the strategy pattern used here.
First put the "variable" classes into Engine's formal parmaeter list:
public abstract class Engine<B extends ExecuteBehavior> {
B executeBehavior;
public void setExecuteBehavior(B executeBehavior) {
this.executeBehavior = executeBehavior;
}
public void performExecution() {
executeBehavior.execute();
}
public abstract void init(String pathToResources);
}
Then you can define the subclasses the way you want:
public class StringEngine extends Engine<RunStringEvaluation> {
public StringEngine() {
executeBehavior = new RunStringEvaluation();
}
#Override
public void init(String pathToResources) {
System.out.println("Initializing StringEngine with resources "+pathToResources);
System.out.println("Successfully initialized StringEngine!");
}
}
In the example code you've provided, you don't need that. Just move setExecuteBehavior to the subclasses and make it private.
It's fairly simple to achieve that using generics, you were totally right trying to use generics for that
All you had to do is to change your classes like this
First the interface
public interface ExecuteBehavior<T> {
void execute();
}
Then the abstract implementation
public abstract class Engine<T> {
ExecuteBehavior<T> executeBehavior;
public void setExecuteBehavior(ExecuteBehavior<T> executeBehavior) {
this.executeBehavior = executeBehavior;
}
public void performExecution() {
executeBehavior.execute();
}
public abstract void init(String pathToResources);
}
And finally the RunNumberEngine and NumberEngine
public class RunNumberEvaluation implements ExecuteBehavior<Number> {
#Override
public void execute() {
// some processing
System.out.println("Running numeric evaluation");
}
}
NumberEngine
public class NumberEngine extends Engine<Number> {
public NumberEngine() {
executeBehavior = new RunNumberEvaluation();
}
#Override
public void init(String pathToResources) {
System.out.println("Initializing NumberEngine with resources "+pathToResources);
System.out.println("Successfully initialized NumberEngine!");
}
}
And RunStringEngine, followed by StringEngine
public class RunStringEvaluation implements ExecuteBehavior<String> {
#Override
public void execute() {
// some processing
System.out.println("Running string evaluation");
}
}
StringEngine
public class StringEngine extends Engine<String> {
public StringEngine() {
executeBehavior = new RunStringEvaluation();
}
#Override
public void init(String pathToResources) {
System.out.println("Initializing StringEngine with resources "+pathToResources);
System.out.println("Successfully initialized StringEngine!");
}
}

Is it possible to "override" an interface through a proxy class?

I have a small set of methods from various classes that I'm exposing through a proxy-like convenience class. My issue is that one of those methods takes as an argument an instance of a class implementing an inner interface. I however, do not want to expose that interface through the original class, and would rather provide it through my proxy.
Here is an example of what I mean:
Class C1 {
public static void addSomeListener(SomeListener listener) {
// Some code
}
public interface someListener {
public void interfaceMethod();
}
}
Class C2 {
public interface someListener {
public void interfaceMethod();
}
public static void doAddListener(SomeListener listener) {
// The compiler, of course, complains here
C1.addSomeListener(listener);
}
}
I'm wondering if it's possible to somehow "override" that interface so that the interface from C2 can be exposed to the user/developer while still keeping the inner interface defined in C1 hidden.
The following should do the job:
class C2 {
public interface SomeOtherListener extends SomeListener {
public void interfaceMethod();
}
public static void doAddListener(SomeOtherListener listener) {
C1.addSomeListener(listener);
}
}

Extending functionality of all implementations of an Interface?

I'm looking to create a set of functions which all implementations of a certain Interface can be extended to use. My question is whether there's a way to do this without using a proxy or manually extending each implementation of the interface?
My initial idea was to see if it was possible to use generics; using a parameterized type as the super type of my implementation...
public class NewFunctionality<T extends OldFunctionality> extends T {
//...
}
...but this is illegal. I don't exactly know why this is illegal, but it does sort of feel right that it is (probably because T could itself be an interface rather than an implementation).
Are there any other ways to achieve what I'm trying to do?
EDIT One example of something I might want to do is to extend java.util.List... Using my dodgy, illegal syntax:
public class FilterByType<T extends List> extends T {
public void retainAll(Class<?> c) {
//..
}
public void removeAll(Class<?> c) {
//..
}
}
You can achieve something like this using a programming pattern known as a 'decorator' (although if the interface is large then unfortunately this is a bit verbose to implement in Java because you need to write single-line implementations of every method in the interface):
public class FilterByType<T> implements List<T> {
private List<T> _list;
public FilterByType(List<T> list) {
this._list = list;
}
public void retainAll(Class<?> c) {
//..
}
public void removeAll(Class<?> c) {
//..
}
// Implement List<T> interface:
public boolean add(T element) {
return _list.add(element);
}
public void add(int index, T element) {
_list.add(index, element);
}
// etc...
}
Alternatively, if the methods don't need to access protected members, then static helper methods are a less clucky alternative:
public class FilterUtils {
public static void retainAll(List<T> list, Class<?> c) {
//..
}
public static void removeAll(List<T> list, Class<?> c) {
//..
}
}
What prevents you from just adding new methods to the interface?
If you can't just add the new functionality to old interface, you could consider making another interface and then an implementation which merely implements those two. Just to be clear, in code this is what I mean:
// Old functionality:
public interface Traveling {
void walk();
}
// Old implementation:
public class Person implements Traveling {
void walk() { System.out.println("I'm walking!"); }
}
// New functionality:
public interface FastTraveling {
void run();
void fly();
}
// New implementation, option #1:
public class SuperHero extends Person implements FastTraveling {
void run() { System.out.println("Zoooom!"); }
void fly() { System.out.println("To the skies!"); }
}
// New implementation, option #2:
public class SuperHero implements Traveling, FastTraveling {
void walk() { System.out.println("I'm walking!"); }
void run() { System.out.println("Zoooom!"); }
void fly() { System.out.println("To the skies!"); }
}
I think it's illegal because you can not guarantee what class T will be. Also there are technical obstacles (parent's class name must be written in bytecode, but Generics information get lost in bytecode).
You can use Decorator pattern like this:
class ListDecorator implements List {
private List decoratingList;
public ListDecorator(List decoratingList){
this.decoratingList = decoratingList;
}
public add(){
decoratingList.add();
}
...
}
class FilterByArrayList extends ListDecorator {
public FilterByAbstractList () {
super(new ArrayList());
}
}
There is a delegation/mixin framework that allows a form of this. You can define a new interface, implement a default implementation of that interface, then request classes which implement that interface but subclass from elsewhere in your hierarchy.
It's called mixins for Java, and there's a webcast right there that demonstrates it.
I'm afraid it's not clear what do you want to get.
Basically, I don't see any benefit in using 'public class NewFunctionality<T extends OldFunctionality> extends T' in comparison with 'public class NewFunctionality extends OldFunctionality' ('public class FilterByType<T extends List> extends T' vs 'public class FilterByType<T> implements List<T>')

Categories

Resources