Take argument that implements several Interfaces for object creation - java

I have object that I want to create using object that implements two interfaces (suppose, I can't modify object's class to create third interface that will be extends two interfaces). What will be the best way to create such objects using guice?

Java does allow you to do interface combinations, i.e.
static class TL<T extends IA & IB> extends TypeLiteral<T>(){}
but you'll notice there really has to be a concrete type T which implements both of these interfaces. Java can't invent "combination types" for variables - a type must exist with an actual class file.
I was surprised to discover that it is indeed possible to do this. I suspect this is a dark corner that Guice's maintainers would suggest not going into, and it is probably not a good idea.
Things to notice about the code below:
I am actually abusing Guice's built-in safeguards by making TL subclass TypeLiteral parameterized on IA instead of TypeLiteral on T which would be correct. So in fact, this entire example probably works by accident.
It doesn't help that much. Something, somewhere finally has to specify a concrete type (the class Both) in this case. It lets you get around specifying a concrete type in the classes which use the object, but not when you bind it or if you request it directly from the injector
Almost nobody understands the TypeA & TypeB syntax with Java generics - prepare for anybody who looks at this code to be completely baffled, even some Java gurus
If you later try to use an object which only implements one of the interfaces, you could create a dynamic proxy which implements one interface and delegates to the object, but you will still need to create an interface which combines the two to give Java a type to refer to
public class X {
static final class TL<T extends IA & IB> extends TypeLiteral<IA> {}
interface IA {}
interface IB {}
static final class Both implements IA, IB {}
#Test
public void test() {
Injector inj = Guice.createInjector(new M());
Both object = inj.getInstance(Key.get(new TypeLiteral<Both>(){}));
assertNotNull(object);
Foo<Both> foo = inj.getInstance(Key.get(new TypeLiteral<Foo<Both>>() {}));
assertTrue (object instanceof IA);
assertTrue (object instanceof IB);
assertNotNull(foo);
assertNotNull(foo.obj);
}
static class Foo<T extends IA & IB> {
private final T obj;
#Inject
Foo(T obj) {
this.obj = obj;
}
}
static class M extends AbstractModule {
#Override
protected void configure() {
bind(new TL<Both>()).to(Both.class);
}
}
}
So I think the answer is, you can but you probably shouldn't.

Either inject one interface and cast to the other when needed or inject the same object twice as two different interfaces.
Both are ugly, I know, but I'd call the whole approach ugly. If you need two different interfaces a single class implements you probably haw a flaw in your object model. If one class implements two disjoint interfaces it has two different aspects and you should probably improve it's cohesion

Why not just do:
// Your original class
class AB implements IA, IB {...}
// In a Module
bind(AB.class).in(SOMESCOPE);
bind(IA.class).to(AB.class);
bind(IB.class).to(AB.class);
// In the object to be inejcted with AB
class MyClass {
#Inject IA a;
#Inject IB b;
}
In the end, you would actually have a == b, wouldn't that fit the bill?

Related

How can I assign an interface variable to a sub-interface variable?

I have these interfaces:
public interface Interface {
int functionOne();
}
public interface SubInterface extends Interface {
String functionTwo();
}
and this class:
public class MyClass implements SubInterface {
...
}
Now here's the problem:
Interface a = new MyClass();
SubInterface b = a;
I'd like to assign the instance of MyClass which a is addressing to the variable b. I don't want to create an identical instance, just transfer the existing one's address from a to b, but if I do it like this, netbeans gives me an error about incompatible types. How do I do it?
Currently, your code will not compile because a is of type Interface and that cannot be assigned to a variable of type SubInterface. thus you'll need to do:
SubInterface b = (MyClass)a;
if you think about it; it makes complete sense as not every implementing type of Interface implements SubInterface.
If you don't know the actual type of the implementing class then you can do:
SubInterface b = (SubInterface) a;
which is much safer.

type of object while implementing interface

Below is my code...
Its not that much complex.
Here I want to understand that In class D, b is an interface type variable and in that variable we are storing reference to new object of class(C) which implements that interface(B). How we are able to assign object of type C to interface B type variable b..? Class and Interface both are of different types then what makes it special when we implements a interface on class and we are able to do it which is my question
public interface A {
}
public interface B {
public A methodABCD();
}
public class C implements B {
final A typeA;
public A methodABCD() {
return typeA;
}
}
public class D {
static private B b;
static public A methodABCD() {
if (b == null) {
b = new C();-------------->How..?
}
return b.methodABCD();
}
}
Ok lets take an Example and illustrate it.
interface Animal {
public void eat();
}
class Human implements Animal{
public void eat(){
// Eat cakes and Buns
}
}
class Dog implements Animal{
public void eat(){
// Eat bones
}
}
Now let see how you can use them
Animal h = new Human();
Animal d = new Dog();
Now at some point you might want to change your Human to behave like a Dog.
h =d;
h.eat();// Eat bones
Your thought became a possibility because, they belongs to the same type. Imagine that there is not Animal interface and see how difficult it is convert a Human to Dog.
You see the flexibility and the advantages in type varying. You are allowed to do that because of they both are Animal nothing but an Interface.
This is valid
B b = new C();
only because C implements the interface B, so you are telling the compiler:
"I need an object B that can do something instead of that is something...", this approach is called programming to interfaces and allows you to latter change the class C for a class F as long as F can do something too, that is a more flexible design...
Java hides the memory addresses of the objects created in Heap. Objects are accessed by the references. One object may have multiple references. Using = operator references are made to refer to an object and using . operator references can invoke a particular behavior of the object. References and objects are stored in different memory locations.
If there is an objext X of class C then as per the Java language specifications an X can have references whose type is C or any super class in higher hierarchy or any interface implemented by C or any of the super class in higher hierarchy or any interface extended by any of these interfaces.
class A implements IA{}
class B extends A implements IB{}
interface IC extends IA{}
interface IB extends ID{}
class E{}
class F extends B{}
Now new B() can have references of type A,B,IA,IB,ID but can not have reference of type E,IC,F as these do not belong to the higher lever hierarchy.
You can use interface as a reference type in java.
It can only refer to objects of those classes that implement that interface.
But remember with interface as reference you can access only those methods that are declared in that interface. Your class may define additional methods but that won't be accessible using the interface reference.
In a way when you say class and interface are of different type you are right but when a class implements an interface it provides definition to all the methods declared in that interface and hence that interface can refer to the implementing class object.
It is kind of like with inheritance.
When a class implements an interface it is bound under a contract to provide implementation to all the methods.
So when a interface refers to a class object you can be pretty sure that that class must have implemented that interface and hence all your methods declaration now have definitions that can be called.
It is because of one of the design principles, Liskov Substituion Principles, L out of SOLID,
if B is a subtype of P, then objects of type P can be replaced with instantiations of type B. Search SOLID design principles on google for more details. An object oriented language follows this

Cyclic Inheritance Of Interfaces

I understand why cyclic inheritance of classes is not allowed in Java but I did not understand why cyclic inheritance of interfaces is not allowed. To illustrate:
interface Foo extends Bar {/*methods and constants*/}
interface Bar extends Foo {/*methods and constants*/}
Interfaces do not need instantiation, then what prevents them from extending each other?
By the way, I read this question but this is not about interfaces but classes:
Cyclic inheritance hierarchy in Java
Thanks in advance.
No, but extension of an interface is a way of splitting up the agreement. Remember, an interface is an agreement to provide an implementation of a set of methods.
public interface A extends B {
public void myMethod();
public void myOtherMethod();
}
You're saying interface A is defined by these methods and all the methods in interface B. Now if interface B says..
public interface B extends A {}
you're saying that interface B is defined by the methods in interface A. Well what defines interface A. A couple of methods and interface B. And what defines interface B? Interface A, which is defined by a couple of methods and interface B! See where this is going?
It makes no logical sense to allow this.
Probably there are no theoretical difficulties, but this would create unnecessary complications. A few to name:
Currently traversal of class interfaces (via recursive calls of Class.getInterfaces()) is guaranteed to produce finite result, probably with repeats, but nevertheless. For example, such code is valid:
private static void fillInterfaces(Class<?> clazz, Set<Class<?>> set) {
if(clazz == null) return;
for (Class<?> iclass : clazz.getInterfaces()) {
set.add(iclass);
fillInterfaces(iclass, set);
}
fillInterfaces(clazz.getSuperclass(), set);
}
public static Set<Class<?>> getAllInterfaces(Class<?> clazz) {
Set<Class<?>> result = new HashSet<>();
fillInterfaces(clazz, result);
return result;
}
Similar code is already written and working in many places. With your proposal supplying the circular interface here would cause an infinite recursion.
Currently (in Java-8) interface can define a default implementation for its parent interface as well, replacing parent implementation if necessary. For example:
interface A {
default public String getX() {return "A";}
}
interface B extends A {
default public String getX() {return "B";}
}
static class C implements A, B {} // ok, C.getX() returns "B"
If now A extends B, then A wins:
interface A extends B {
default public String getX() {return "A";}
}
interface B {
default public String getX() {return "B";}
}
static class C implements A, B {} // ok, C.getX() returns "A"
But what if both A extends B and B extends A? Who will win? What new C().getX() will print? Or should it be new type of compilation error?
In general it seems that such feature would bring more problems than produce benefits.
See Java Language Specification 9.1.3 Superinterfaces and Subinterfaces :
An interface I depends on a reference type T if any of the following is true:
I directly depends on T.
I directly depends on a class C that depends on T (§8.1.5).
I directly depends on an interface J that depends on T (using this definition recursively).
It is a compile-time error if an interface depends on itself.
If circularly declared interfaces are detected at run time, as interfaces are loaded, then a ClassCircularityError is thrown (§12.2.1).
As for why, I like Andy Turner's comment:
If Foo extends Bar, then every instance of Foo is also a Bar. If Bar extends Foo, then every instance of Bar is also a Foo. If both were allowed to be true, then the only way the two conditions can be satisfied is if Foo == Bar.

Cast object to interface did not implement?

First I know this is quite dirty job, and if there is a way, it may be consider "bad practice". Unfortunately, I have to explore the possibility.
I would like to know if I can cast an object that in practice implements a Interface but in fact do not. I mean, the class implements all the methods but do not have the "implement interface" in the declaration. Additionally, I would prefer to do this and finally get the Object typed. Example below
interface IA{
void method();
}
class CB{
void method(){;}
}
public class foo{
public static void main(String[] args){
/*magic to cast the object without exception*/
IA ob= (IA) new CB();
ob.method();
}
}
I want to get this IA object at the end.
Consider a much safer alternative.
Wrap the object you want to cast, into a class that implements the interface and delegate the method calls to the wrapped object.
Example:
public class CBWrapper implements IA {
CB target;
public CBWrapper(CB target) {
this.target = target;
}
#Override
void method() {
target.method();
}
}
You cannot cast an Object to interface it doesn't implements.
You can access object's method using reflection and call a specific method by name or whatever.
However, I think you should ask yourself what you want to do and is there a simpler way to do it.
How the implements keyword is used to get the IS-A relationship?
The implements keyword is used by classes by inherit from interfaces.
Interfaces can never be extended by the classes.
You can’t create an object from an interface because in Java interfaces don't have a constructor.
A better way would be to play with softer alternatives.

Interfaces usage

Can you have a class which implements an interface, and choose whether to use the methods in the interface during instantiation of this class? Therefore having object A which uses the interface and object B which does not use it.
Thanks
Updated:
Assuming you have a Professor class and this class implements an interface called Employer, which has employ(rAssist x) abstract method.
Now I want to instantiated 2 objects from the Professor class implementing this interface Object A - Professor can employ a research assistant and Object B - Professor cannot employ research assistants.
Can you have a class which implements an interface, and choose whether to use the methods in the interface during instantiation of this class?
No, if class C implements the interface, then all instances of C will provide the methods declared in the interface.
What you can do is something like
class MyClass implements MyInterface {
#Override
void interfaceMethod() {
System.out.println("Interface method");
}
}
and then do
MyClass x = new MyClass();
MyClass y = new MyClass() {
#Override
void interfaceMethod() {
throw new UnsupportedOperationException();
}
};
In effect, x supports the use of interfaceMethod while y does not. Note however that...
The usage of y.interfaceMethod is not prevented at compile-time, i.e. it will not be enforced by the type system.
With this solution, you are in fact creating an (anonymous) subclass of MyClass and assigning an instance of it to y.
Do you mean you want class A and Class B to implement a common Interface but you dont want to implement all methods in Class B?
An Interface in simple terms means it is sort of a contract and all the classes which implement it should follow that contract.So if you want Class B to implement the interface , Class B should also follow the same contract. But if you dont want to implement any methos you can always do this.
class ISampleInterface {
void sampleMethod();
void optionalMethod();
}
Class A implements ISampleInterface {
void sampleMethod() {
//Your Implementation
}
void optionalMethod() {
//Your Implementation
}
}
class B implements ISampleInterface {
void sampleMethod() {
//Your Implementation
}
void optionalMethod() {
throw new UnsupportedMethodException();
}
}
No, that's not the point of an Interface.
An Interface is contract that guarantees that implementations WILL implement it's signature
The idea of interface is to establish a obligation for the class that implements the interface.
If your's is a requirement, you can use the java.lang.reflect.Method reflection class to change the visibility of the method at runtime. However, this is not a clean way.
1. Interfaces were introduced in Java because Multiple Inheritance was not allowed in Java.
2. But as far as Design Pattern are concerned, following are the uses..
- To implement certain Roles.
Consider Dog a Super class, but then Pet dog and Wild dog can be interfaces, which
can be implemented by the Sub Classes of Dog class.
- Used when Behaviors keeps changing.
Consider you have a Class Drawing, and paint method() in it, now paint can be stroking, shading, etc...
You must Encapsulate such behaviors in an Interface or an Abstract class.

Categories