Change an object's implemented interfaces at runtime - java

Is it possible to dynamically add to the list of interfaces implemented by an object (such that instanceof returns true and casts don't fail)?
I have a set of objects whose types need to change dynamically during runtime. As their state changes, more of their methods/properties become valid. Currently, this is done in a "brute-force" way... all members are exposed, and calling the wrong one at the wrong time is a bug. Ideally, I would like to use static typing, and to pass these objects to methods which expect specific interfaces. The set of interfaces that an object implements will only increase, so old references would remain valid.
Is it possible to change an object's implemented interfaces at runtime, either using built-in reflection or via third-party bytecode manipulation?

You can use a Proxy but as the comments suggest - this is almost always not the best option.
You would be better to craft you object as multifaceted.
interface Interface1 {
String getI1();
}
interface Interface2 {
String getI2();
}
class Multifaceted {
String i1;
String i2;
private final Interface1 asInterface1 = new Interface1() {
#Override
public String getI1() {
return i1;
}
};
private final Interface2 asInterface2 = new Interface2() {
#Override
public String getI2() {
return i2;
}
};
public Interface1 asInterface1() {
if ( i1 == null ) {
throw new InvalidStateException("I am not ready to be one of these yet!");
}
return asInterface1;
}
public Interface2 asInterface2() {
return asInterface2;
}
}

Related

Call method of unknown object

I have two ArrayLists - ArrayList1 and ArrayList2. Each of them is filled with objects - Object1 and Object2, respectively.
Both of these objects have method 'getText'.
Object1:
public String getText() { return "1";}
Object2:
public String getText() { return "2";}
At certain point I would like to loop through each of these lists using the same method (just with different parameter).
loopThroughList(1)
loopThroughList(2)
What is the syntax if I want to call a method, but I don't know which object it is going to be? This is the code I have so far:
for (Object o : lists.getList(listNumber)) {
System.out.println(o.getText());
}
It says Cannot resolve method getText. I googled around and found another solution:
for (Object o : lists.getList(listNumber)) {
System.out.println(o.getClass().getMethod("getText"));
}
But this gives me NoSuchMethodException error. Even though the 'getText' method is public.
EDIT: To get the correct list, I am calling the method 'getList' of a different object (lists) that returns either ArrayList1 or ArrayList2 (depending on the provided parameter).
class Lists
public getList(list) {
if (list == 1) {
return ArrayList1;
}
else if (list == 2) {
return ArrayList2;
}
}
Define an interface for the getText method
public interface YourInterface {
String getText();
}
Implement the interface on the respective classes
public class Object1 implements YourInterface {
#Override
public String getText() {
return "1";
}
}
public class Object2 implements YourInterface {
#Override
public String getText() {
return "2";
}
}
Modify your getList method to return List<YourInterface>
public static List<YourInterface> getList(int list){
List<YourInterface> result = new ArrayList<>();
if(list == 1){
// your initial type
List<Object1> firstList = new ArrayList<>();
result.addAll(firstList);
} else {
// your initial type
List<Object2> secondList = new ArrayList<>();
result.addAll(secondList);
}
return result;
}
Declaration for loopThroughList
public static void loopThroughList(List<YourInterface> list){
list.forEach(yourInterface -> System.out.println(yourInterface.getText()));
}
Sample usage.
public static void main(String[] args) {
loopThroughList(getList(1));
loopThroughList(getList(2));
}
Interfaces work great here, but there a couple of other options if you're dealing with legacy code and cannot use interfaces.
First would be to cast the list items into their respective types:
for (Object o : lists.getList(listNumber)) {
if(o instanceof Object1) {
Object1 o1 = (Object1)o;
System.out.println(o1.getText());
}
else if(o instanceof Object2) {
Object1 o2 = (Object2)o;
System.out.println(o2.getText());
}
else {
System.out.println("Unknown class");
}
}
You can also use reflection to see if the object has a getText method and then invoke it:
for (Object o : lists.getList(listNumber)) {
try {
System.out.println(o.getClass().getDeclaredMethod("getName").invoke(o));
}
catch(Exception e) {
System.out.println("Object doesn't have getText method");
}
}
This is awful. Can you elaborate on what specifically you are trying to do? Java is strong typed by design, and you are trying to get around it. Why? Instead of Object, use the specific class, or interface as previously suggested. If that's not possible, and you must use lists of Objects, use instanceof and casting eg:
for (Object o : lists.getList(listNumber)) {
if (o instanceof Object1) {
Object1 o1 = (Object1) o;
System.out.println(o1.getText());
} else if (o instanceof Object2) {
Object2 o2 = (Object2) o;
System.out.println(o2.getText());
}
}
This is where interfaces come in.
interface HasText {
public String getText();
}
class Object1 implements HasText {
#Override
public String getText() {
return "1";
}
}
class Object2 implements HasText {
#Override
public String getText() {
return "2";
}
}
private void test() {
List<HasText> list = Arrays.asList(new Object1(), new Object2());
for (HasText ht : list) {
System.out.println(ht);
}
}
If one of your objects is not in your control you can use a Wrapper class.
class Object3DoesNotImplementHasText {
public String getText() {
return "3";
}
}
class Object3Wrapper implements HasText{
final Object3DoesNotImplementHasText it;
public Object3Wrapper(Object3DoesNotImplementHasText it) {
this.it = it;
}
#Override
public String getText() {
return it.getText();
}
}
private void test() {
List<HasText> list = Arrays.asList(new Object1(), new Object2(), new Object3Wrapper(new Object3DoesNotImplementHasText()));
for (HasText ht : list) {
System.out.println(ht);
}
}
Just to add more to this answer and give you some more to think on this (Will try to do it in a simple, non-formal way). Using interfaces is the proper way of doing such operation. However, I want to stand on the "bad idea":
for (Object o : lists.getList(listNumber)) {
System.out.println(o.getClass().getMethod("getText"));
}
What you are doing here, is using a mechanism called Reflection:
Reflection is a feature in the Java programming language. It allows an
executing Java program to examine or "introspect" upon itself, and
manipulate internal properties of the program. For example, it's
possible for a Java class to obtain the names of all its members and
display them.
What you actually attempted, is using that mechanism, to retrieve the method through a Class reflection object instance of your Class (sounds weird, isn't it?).
From that perspective, you need to think that, if you want to invoke your method, you now have, in a sense, a meta-Class instance to manipulate your objects. Think of it like an Object that is one step above your Objects (Similarly to a dream inside a dream, in Inception). In that sense, you need to retrieve the method, and then invoke it in a different (meta-like) way:
java.lang.reflect.Method m = o.getClass().getMethod("getText");
m.invoke(o);
Using that logic, you could possibly iterate through the object list, check if method exists, then invoke your method.
This is though a bad, BAD idea.
Why? Well, the answer relies on reflection itself: reflection is directly associated with runtime - i.e. when the program executes, practically doing all things at runtime, bypassing the compilation world.
In other words, by doing this, you are bypassing the compilation error mechanism of Java, allowing such errors happen in runtime. This can lead to unstable behavior of the program while executing - apart from the performance overhead using Reflection, which will not analyze here.
Side note: While using reflection will require the usage of Checked Exception handling, it still is not a good idea of doing this - as you practically try to duck tape a bad solution.
On the other hand, you can follow the Inheritance mechanism of Java through Classes and Interfaces - define an interface with your method (let's call it Textable), make sure that your classes implement it, and then use it as your base object in your list declaration (#alexrolea has implemented this in his answer, as also #OldCurmudgeon has).
This way, your program will still make the method call decision making at Runtime (via a mechanism called late binding), but you will not bypass the compilation error mechanism of Java. Think about it: what would happen if you define a Textable implementation without providing the class - a compile error! And what if you set a non-Textable object into the list of Textables? Guess what! A compile error again. And the list goes on....
In general, avoid using Reflection when you are able to do so. Reflection is useful in some cases that you need to handle your program in such a meta-way and there is no other way of making such things. This is not the case though.
UPDATE: As suggested by some answers, you can use instanceof to check if you have a specific Class object instance that contains your method, then invoke respectively. While this seems a simple solution, it is bad in terms of scaling: what if you have 1000 different classes that implement the same method you want to call?
your objects have to implement a common interface.
interface GetTextable {
String getText();
}
class One implements GetTextable {
private final String text;
public One(final String text) {
this.text = text;
}
public String getText() {
return this.text;
}
}
class Two implements GetTextable {
private final String text;
public Two(final String text) {
this.text = text;
}
public String getText() {
return this.text;
}
}
#Test
public void shouldIterate() throws Exception {
List<GetTextable> toIterate = Arrays.asList(new One("oneText"), new Two("twoText"));
for(GetTextable obj: toIterate) {
System.out.println(obj.getText());
}
}

Using enum to implement multitons in Java

I would like to have a limited fixed catalogue of instances of a certain complex interface. The standard multiton pattern has some nice features such as lazy instantiation. However it relies on a key such as a String which seems quite error prone and fragile.
I'd like a pattern that uses enum. They have lots of great features and are robust. I've tried to find a standard design pattern for this but have drawn a blank. So I've come up with my own but I'm not terribly happy with it.
The pattern I'm using is as follows (the interface is highly simplified here to make it readable):
interface Complex {
void method();
}
enum ComplexItem implements Complex {
ITEM1 {
protected Complex makeInstance() { return new Complex() { ... }
},
ITEM2 {
protected Complex makeInstance() { return new Complex() { ... }
};
private Complex instance = null;
private Complex getInstance() {
if (instance == null) {
instance = makeInstance();
}
return instance;
}
protected void makeInstance() {
}
void method {
getInstance().method();
}
}
This pattern has some very nice features to it:
the enum implements the interface which makes its usage pretty natural: ComplexItem.ITEM1.method();
Lazy instantiation: if the construction is costly (my use case involves reading files), it only occurs if it's required.
Having said that it seems horribly complex and 'hacky' for such a simple requirement and overrides enum methods in a way which I'm not sure the language designers intended.
It also has another significant disadvantage. In my use case I'd like the interface to extend Comparable. Unfortunately this then clashes with the enum implementation of Comparable and makes the code uncompilable.
One alternative I considered was having a standard enum and then a separate class that maps the enum to an implementation of the interface (using the standard multiton pattern). That works but the enum no longer implements the interface which seems to me to not be a natural reflection of the intention. It also separates the implementation of the interface from the enum items which seems to be poor encapsulation.
Another alternative is to have the enum constructor implement the interface (i.e. in the pattern above remove the need for the 'makeInstance' method). While this works it removes the advantage of only running the constructors if required). It also doesn't resolve the issue with extending Comparable.
So my question is: can anyone think of a more elegant way to do this?
In response to comments I'll tried to specify the specific problem I'm trying to solve first generically and then through an example.
There are a fixed set of objects that implement a given interface
The objects are stateless: they are used to encapsulate behaviour only
Only a subset of the objects will be used each time the code is executed (depending on user input)
Creating these objects is expensive: it should only be done once and only if required
The objects share a lot behaviour
This could be implemented with separate singleton classes for each object using separate classes or superclasses for shared behaviour. This seems unnecessarily complex.
Now an example. A system calculates several different taxes in a set of regions each of which has their own algorithm for calculting the taxes. The set of regions is expected to never change but the regional algorithms will change regularly. The specific regional rates must be loaded at run time via remote service which is slow and expensive. Each time the system is invoked it will be given a different set of regions to calculate so it should only load the rates of the regions requested.
So:
interface TaxCalculation {
float calculateSalesTax(SaleData data);
float calculateLandTax(LandData data);
....
}
enum TaxRegion implements TaxCalculation {
NORTH, NORTH_EAST, SOUTH, EAST, WEST, CENTRAL .... ;
private loadRegionalDataFromRemoteServer() { .... }
}
Recommended background reading: Mixing-in an Enum
Seems fine. I would make initialization threadsafe like this:
enum ComplexItem implements Complex {
ITEM1 {
protected Complex makeInstance() {
return new Complex() { public void method() { }};
}
},
ITEM2 {
protected Complex makeInstance() {
return new Complex() { public void method() { }}
};
private volatile Complex instance;
private Complex getInstance() {
if (instance == null) {
createInstance();
}
return instance;
}
protected abstract Complex makeInstance();
protected synchronized void createInstance() {
if (instance == null) {
instance = makeInstance();
}
}
public void method() {
getInstance().method();
}
}
The modifier synchronized only appears on the createInstance() method, but wraps the call to makeInstance() - conveying threadsafety without putting a bottleneck on calls to getInstance() and without the programmer having to remember to add synchronized to each to makeInstance() implementation.
This works for me - it's thread-safe and generic. The enum must implement the Creator interface but that is easy - as demonstrated by the sample usage at the end.
This solution breaks the binding you have imposed where it is the enum that is the stored object. Here I only use the enum as a factory to create the object - in this way I can store any type of object and even have each enum create a different type of object (which was my aim).
This uses a common mechanism for thread-safety and lazy instantiation using ConcurrentMap of FutureTask.
There is a small overhead of holding on to the FutureTask for the lifetime of the program but that could be improved with a little tweaking.
/**
* A Multiton where the keys are an enum and each key can create its own value.
*
* The create method of the key enum is guaranteed to only be called once.
*
* Probably worth making your Multiton static to avoid duplication.
*
* #param <K> - The enum that is the key in the map and also does the creation.
*/
public class Multiton<K extends Enum<K> & Multiton.Creator> {
// The map to the future.
private final ConcurrentMap<K, Future<Object>> multitons = new ConcurrentHashMap<K, Future<Object>>();
// The enums must create
public interface Creator {
public abstract Object create();
}
// The getter.
public <V> V get(final K key, Class<V> type) {
// Has it run yet?
Future<Object> f = multitons.get(key);
if (f == null) {
// No! Make the task that runs it.
FutureTask<Object> ft = new FutureTask<Object>(
new Callable() {
public Object call() throws Exception {
// Only do the create when called to do so.
return key.create();
}
});
// Only put if not there.
f = multitons.putIfAbsent(key, ft);
if (f == null) {
// We replaced null so we successfully put. We were first!
f = ft;
// Initiate the task.
ft.run();
}
}
try {
/**
* If code gets here and hangs due to f.status = 0 (FutureTask.NEW)
* then you are trying to get from your Multiton in your creator.
*
* Cannot check for that without unnecessarily complex code.
*
* Perhaps could use get with timeout.
*/
// Cast here to force the right type.
return type.cast(f.get());
} catch (Exception ex) {
// Hide exceptions without discarding them.
throw new RuntimeException(ex);
}
}
enum E implements Creator {
A {
public String create() {
return "Face";
}
},
B {
public Integer create() {
return 0xFace;
}
},
C {
public Void create() {
return null;
}
};
}
public static void main(String args[]) {
try {
Multiton<E> m = new Multiton<E>();
String face1 = m.get(E.A, String.class);
Integer face2 = m.get(E.B, Integer.class);
System.out.println("Face1: " + face1 + " Face2: " + Integer.toHexString(face2));
} catch (Throwable t) {
t.printStackTrace(System.err);
}
}
}
In Java 8 it is even easier:
public class Multiton<K extends Enum<K> & Multiton.Creator> {
private final ConcurrentMap<K, Object> multitons = new ConcurrentHashMap<>();
// The enums must create
public interface Creator {
public abstract Object create();
}
// The getter.
public <V> V get(final K key, Class<V> type) {
return type.cast(multitons.computeIfAbsent(key, k -> k.create()));
}
}
One thought about this pattern: the lazy instantiation isn't thread safe. This may or may not be okay, it depends on how you want to use it, but it's worth knowing. (Considering that enum initialisation in itself is thread-safe.)
Other than that, I can't see a simpler solution that guarantees full instance control, is intuitive and uses lazy instantiation.
I don't think it's an abuse of enum methods either, it doesn't differ by much from what Josh Bloch's Effective Java recommends for coding different strategies into enums.

Is there a way to instantiate a child class with parent object in java?

I have a base class say
class A {
private String name;
private String age;
//setters and getters for same
}
and a child class say
class B extends A {
private String phone;
private String address;
//setters and getters for same
}
now I've an instance of A and besides this I have to set the fields in B as well, so code would be like,
A instanceOfA = gotAFromSomewhere();
B instanceOfB = constructBFrom(instanceOfA);
instanceOfB.setPhone(getPhoneFromSomewhere());
instanceOfB.setAddress(getAddressFromSomewhere());
can I instantiate B with given A, but I don't want to do this way,
B constructBFrom(A instanceOfA) {
final B instanceOfB = new B();
instanceOfB.setName(instanceOfA.getName());
instanceOfB.setPhone(instanceOfA.getAge());
return B;
}
rather what I'd love to have some utility with function which is generic enough to construct object as in,
public class SomeUtility {
public static <T1, T2> T2 constructFrom(T1 instanceOfT1, Class<T2> className) {
T2 instatnceOfT2 = null;
try {
instatnceOfT2 = className.newInstance();
/*
* Identifies the fields in instanceOfT1 which has same name in T2
* and sets only these fields and leaves the other fields as it is.
*/
} catch (InstantiationException | IllegalAccessException e) {
// handle exception
}
return instatnceOfT2;
}
}
so that I can use it as,
B constructBFrom(A instanceOfA) {
return SomeUtility.constructFrom(instanceOfA, B.class);
}
Moreover, use case will not be only limited to parent-child classes, rather this utility function can be used for adapter use cases.
PS- A and B are third party classes I've to use these classes only so I can't do any modifications
in A and B.
The good practice is to have a factory class which "produces" the instances of B.
public class BFactory {
public B createBFromA(A a) { ... }
}
You have to write the code of the factory method as there is no standard way of creating a child class based on its parent class. It's always specific and depends on the logic of your classes.
However, consider if it is really what you need. There are not many smart use cases for instantiating a class based on the instance of its parent. One good example is ArrayList(Collection c) - constructs a specific list ("child") containing the elements of the generic collection ("base").
Actually, for many situation there is a pattern to avoid such strange constructs. I am aware it's probably not applicable to your specific case as you wrote that your Base and Child are 3rd party classes. However your question title was generic enough so I think you may find the following useful.
Create an interface IBase
Let the class Base implement the interface
Use composition instead of inheritance - let Child use Base instead of inheriting it
Let Child implement IBase and delegate all the methods from IBase to the instance of Base
Your code will look like this:
public interface IBase {
String getName();
int getAge();
}
public class Base implements IBase {
private String name;
private int age;
// getters implementing IBase
}
public class Child implements IBase {
// composition:
final private IBase base;
public Child(IBase base) {
this.base = base;
}
// delegation:
public String getName() {
return base.getName();
}
public int getAge() {
return base.getAge();
}
}
After you edited your question, I doubt even stronger that what you want is good. Your question looks more like an attempt of a hack, of violating (or not understanding) the principles of class-based object oriented concept. Sounds to me like someone coming from the JavaScript word and trying to keep the JavaScript programming style and just use a different syntax of Java, instead of adopting a different language philosophy.
Fun-fact: Instantiating a child object with parent object is possible in prototype-based languages, see the example in JavaScript 1.8.5:
var base = {one: 1, two: 2};
var child = Object.create(base);
child.three = 3;
child.one; // 1
child.two; // 2
child.three; // 3
In my opinion the way you want to avoid is very appropriate. There must be a piece of such code somewhere.
If you can't put that method in the target class just put it somewhere else (some factory). You should additionaly make your method static.
Take a look at Factory method pattern.
2nd option would be extending B and place this method as factory static method in that new class. But this solution seems to be more complicated for me. Then you could call NewB.fromA(A). You should be able then use your NewB instead of B then.
You could do it via reflection:
public static void copyFields(Object source, Object target) {
Field[] fieldsSource = source.getClass().getFields();
Field[] fieldsTarget = target.getClass().getFields();
for (Field fieldTarget : fieldsTarget)
{
for (Field fieldSource : fieldsSource)
{
if (fieldTarget.getName().equals(fieldSource.getName()))
{
try
{
fieldTarget.set(target, fieldSource.get(source));
}
catch (SecurityException e)
{
}
catch (IllegalArgumentException e)
{
}
catch (IllegalAccessException e)
{
}
break;
}
}
}
}
*Above code copied from online tutorial

Anonymous or real class definition when using visitor pattern?

When you use the Visitor pattern and you need to get a variable inside visitor method, how to you proceed ?
I see two approaches. The first one uses anonymous class :
// need a wrapper to get the result (which is just a String)
final StringBuild result = new StringBuilder();
final String concat = "Hello ";
myObject.accept(new MyVisitor() {
#Override
public void visit(ClassA o)
{
// this concatenation is expected here because I've simplified the example
// normally, the concat var is a complex object (like hashtable)
// used to create the result variable
// (I know that concatenation using StringBuilder is ugly, but this is an example !)
result.append(concat + "A");
}
#Override
public void visit(ClassB o)
{
result.append(concat + "B");
}
});
System.out.println(result.toString());
Pros & Cons :
Pros : you do not need to create a class file for this little behavior
Cons : I don't like the "final" keyword in this case : the anonymous class is less readable because it calls external variables and you need to use a wrapper to get the requested value (because with the keyword final, you can't reassign the variable)
Another way to do it is to do an external visitor class :
public class MyVisitor
{
private String result;
private String concat;
public MyVisitor(String concat)
{
this.concat = concat;
}
#Override
public void visit(ClassA o)
{
result = concat + "A";
}
#Override
public void visit(ClassB o)
{
result = concat + "B";
}
public String getResult()
{
return result;
}
}
MyVisitor visitor = new MyVisitor("Hello ");
myObject.accept(visitor);
System.out.println(visitor.getResult());
Pros & Cons :
Pros : all variables are defined in a clean scope, you don't need a wrapper to encapsulate the requested variable
Cons : need an external file, the getResult() method must be call after the accept method, this is quite ugly because you need to know the function call order to correctly use the visitor
You, what's your approach in this case ? Preferred method ? another idea ?
Well, both approaches are valid and imo, it really depends on whether you would like to reuse the code or not. By the way, your last 'Con' point is not totally valid since you do not need an 'external file' to declare a class. It might very well be an inner class...
That said, the way I use Visitors is like this:
public interface IVisitor<T extends Object> {
public T visit(ClassA element) throws VisitorException;
public T visit(ClassB element) throws VisitorException;
}
public interface IVisitable {
public <T extends Object> T accept(final IVisitor<T> visitor) throws VisitorException;
}
public class MyVisitor implements IVisitor<String> {
private String concat;
public MyVisitor(String concat) {
this.concat = concat;
}
public String visit(ClassA classA) throws VisitorException {
return this.concat + "A";
}
public String visit(ClassB classB) throws VisitorException {
return this.concat + "B";
}
}
public class ClassA implements IVisitable {
public <T> T accept(final IVisitor<T> visitor) throws VisitorException {
return visitor.visit(this);
}
}
public class ClassB implements IVisitable {
public <T> T accept(final IVisitor<T> visitor) throws VisitorException {
return visitor.visit(this);
}
}
// no return value needed?
public class MyOtherVisitor implements IVisitor<Void> {
public Void visit(ClassA classA) throws VisitorException {
return null;
}
public Void visit(ClassB classB) throws VisitorException {
return null;
}
}
That way, the visited objects are ignorant of what the visitor wants to do with them, yet they do return whatever the visitor wants to return. Your visitor can even 'fail' by throwing an exception.
I wrote the first version of this a few years ago and so far, it has worked for me in every case.
Disclaimer: I just hacked this together, quality (or even compilation) not guaranteed. But you get the idea... :)
I do not see an interface being implemented in your second example, but I believe it is there. I would add to your interface (or make a sub interface) that has a getResult() method on it.
That would help both example 1 and 2. You would not need a wrapper in 1, because you can define the getResult() method to return the result you want. In example 2, because getResult() is a part of your interface, there is no function that you 'need to know'.
My preference would be to create a new class, unless each variation of the class is only going to be used once. In which case I would inline it anonymously.
From the perspective of a cleaner design, the second approach is preferrable for the same exact reasons you've already stated.
In a normal TDD cycle I would start off with an anonymous class and refactored it out a bit later. However, if the visitor would only be needed in that one place and its complexity would match that of what you've provided in the example (i.e. not complex), I would have left it hanging and refactor to a separate class later if needed (e.g. another use case appeared, complexity of the visitor/surrounding class increased).
I would recommend using the second approach. Having the visitor in its full fledged class also serves the purpose of documentation and clean code. I do not agree with the cons that you have mentioned with the approach. Say you have an arraylist, and you don't add any element to it and do a get, surely you will get a null but that doesn't mean that it is necessarily wrong.
One of the points of the visitor pattern is to allow for multiple visitor types. If you create an anonymous class, you are kind of breaking the pattern.
You should change your accept method to be
public void accept(Visitor visitor) {
visitor.visit(this);
}
Since you pass this into the visitor, this being the object that is visited, the visitor can access the object's property according to the standard access rules.

Java - Method name collision in interface implementation

If I have two interfaces , both quite different in their purposes , but with same method signature , how do I make a class implement both without being forced to write a single method that serves for the both the interfaces and writing some convoluted logic in the method implementation that checks for which type of object the call is being made and invoke proper code ?
In C# , this is overcome by what is called as explicit interface implementation. Is there any equivalent way in Java ?
No, there is no way to implement the same method in two different ways in one class in Java.
That can lead to many confusing situations, which is why Java has disallowed it.
interface ISomething {
void doSomething();
}
interface ISomething2 {
void doSomething();
}
class Impl implements ISomething, ISomething2 {
void doSomething() {} // There can only be one implementation of this method.
}
What you can do is compose a class out of two classes that each implement a different interface. Then that one class will have the behavior of both interfaces.
class CompositeClass {
ISomething class1;
ISomething2 class2;
void doSomething1(){class1.doSomething();}
void doSomething2(){class2.doSomething();}
}
There's no real way to solve this in Java. You could use inner classes as a workaround:
interface Alfa { void m(); }
interface Beta { void m(); }
class AlfaBeta implements Alfa {
private int value;
public void m() { ++value; } // Alfa.m()
public Beta asBeta() {
return new Beta(){
public void m() { --value; } // Beta.m()
};
}
}
Although it doesn't allow for casts from AlfaBeta to Beta, downcasts are generally evil, and if it can be expected that an Alfa instance often has a Beta aspect, too, and for some reason (usually optimization is the only valid reason) you want to be able to convert it to Beta, you could make a sub-interface of Alfa with Beta asBeta() in it.
If you are encountering this problem, it is most likely because you are using inheritance where you should be using delegation. If you need to provide two different, albeit similar, interfaces for the same underlying model of data, then you should use a view to cheaply provide access to the data using some other interface.
To give a concrete example for the latter case, suppose you want to implement both Collection and MyCollection (which does not inherit from Collection and has an incompatible interface). You could provide a Collection getCollectionView() and MyCollection getMyCollectionView() functions which provide a light-weight implementation of Collection and MyCollection, using the same underlying data.
For the former case... suppose you really want an array of integers and an array of strings. Instead of inheriting from both List<Integer> and List<String>, you should have one member of type List<Integer> and another member of type List<String>, and refer to those members, rather than try to inherit from both. Even if you only needed a list of integers, it is better to use composition/delegation over inheritance in this case.
The "classical" Java problem also affects my Android development...
The reason seems to be simple:
More frameworks/libraries you have to use, more easily things can be out of control...
In my case, I have a BootStrapperApp class inherited from android.app.Application,
whereas the same class should also implement a Platform interface of a MVVM framework in order to get integrated.
Method collision occurred on a getString() method, which is announced by both interfaces and should have differenet implementation in different contexts.
The workaround (ugly..IMO) is using an inner class to implement all Platform methods, just because of one minor method signature conflict...in some case, such borrowed method is even not used at all (but affected major design semantics).
I tend to agree C#-style explicit context/namespace indication is helpful.
The only solution that came in my mind is using referece objects to the one you want to implent muliple interfaceces.
eg: supposing you have 2 interfaces to implement
public interface Framework1Interface {
void method(Object o);
}
and
public interface Framework2Interface {
void method(Object o);
}
you can enclose them in to two Facador objects:
public class Facador1 implements Framework1Interface {
private final ObjectToUse reference;
public static Framework1Interface Create(ObjectToUse ref) {
return new Facador1(ref);
}
private Facador1(ObjectToUse refObject) {
this.reference = refObject;
}
#Override
public boolean equals(Object obj) {
if (obj instanceof Framework1Interface) {
return this == obj;
} else if (obj instanceof ObjectToUse) {
return reference == obj;
}
return super.equals(obj);
}
#Override
public void method(Object o) {
reference.methodForFrameWork1(o);
}
}
and
public class Facador2 implements Framework2Interface {
private final ObjectToUse reference;
public static Framework2Interface Create(ObjectToUse ref) {
return new Facador2(ref);
}
private Facador2(ObjectToUse refObject) {
this.reference = refObject;
}
#Override
public boolean equals(Object obj) {
if (obj instanceof Framework2Interface) {
return this == obj;
} else if (obj instanceof ObjectToUse) {
return reference == obj;
}
return super.equals(obj);
}
#Override
public void method(Object o) {
reference.methodForFrameWork2(o);
}
}
In the end the class you wanted should something like
public class ObjectToUse {
private Framework1Interface facFramework1Interface;
private Framework2Interface facFramework2Interface;
public ObjectToUse() {
}
public Framework1Interface getAsFramework1Interface() {
if (facFramework1Interface == null) {
facFramework1Interface = Facador1.Create(this);
}
return facFramework1Interface;
}
public Framework2Interface getAsFramework2Interface() {
if (facFramework2Interface == null) {
facFramework2Interface = Facador2.Create(this);
}
return facFramework2Interface;
}
public void methodForFrameWork1(Object o) {
}
public void methodForFrameWork2(Object o) {
}
}
you can now use the getAs* methods to "expose" your class
You can use an Adapter pattern in order to make these work. Create two adapter for each interface and use that. It should solve the problem.
All well and good when you have total control over all of the code in question and can implement this upfront.
Now imagine you have an existing public class used in many places with a method
public class MyClass{
private String name;
MyClass(String name){
this.name = name;
}
public String getName(){
return name;
}
}
Now you need to pass it into the off the shelf WizzBangProcessor which requires classes to implement the WBPInterface... which also has a getName() method, but instead of your concrete implementation, this interface expects the method to return the name of a type of Wizz Bang Processing.
In C# it would be a trvial
public class MyClass : WBPInterface{
private String name;
String WBPInterface.getName(){
return "MyWizzBangProcessor";
}
MyClass(String name){
this.name = name;
}
public String getName(){
return name;
}
}
In Java Tough you are going to have to identify every point in the existing deployed code base where you need to convert from one interface to the other. Sure the WizzBangProcessor company should have used getWizzBangProcessName(), but they are developers too. In their context getName was fine. Actually, outside of Java, most other OO based languages support this. Java is rare in forcing all interfaces to be implemented with the same method NAME.
Most other languages have a compiler that is more than happy to take an instruction to say "this method in this class which matches the signature of this method in this implemented interface is it's implementation". After all the whole point of defining interfaces is to allow the definition to be abstracted from the implementation. (Don't even get me started on having default methods in Interfaces in Java, let alone default overriding.... because sure, every component designed for a road car should be able to get slammed into a flying car and just work - hey they are both cars... I'm sure the the default functionality of say your sat nav will not be affected with default pitch and roll inputs, because cars only yaw!

Categories

Resources