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.
Related
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
Given an interface like this
public interface MyInterface1<T extends MyAbstractClass> {
...
}
I want to make another interface MyInterface2 taking a MyInterface1 as a generic type and in MyInterface2 I want to reference the actual types of the actual MyInterface1
public interface MyInterface2<INTERFACE extends MyInterface1<MYCLASS>> {
MYCLASS returnInstanceOfMyClass();
}
So I want to say that method "returnInstanceOfMyClass" returns the actual T of the actual MyInterface1 given to MyInterface2.
The thing is that I am not allowed to write the following
public interface MyInterface2<INTERFACE extends MyInterface1<MYCLASS>> {
I am allowed to write
public interface MyInterface2<INTERFACE extends MyInterface1<?>> {
but then I am not able to reference the actual type of T in MyInterface1 in the method signature in MyInterface2 - because I have given it no name to be used when referencing.
I want to be able to do the following in a type-safe way
class MyClass extends MyAbstractClass {
...
}
MyClass c = new MyInterface2<MyInterface1<MyClass>>.returnInstanceOfMyClass();
No casting to MyClass should be necessary, because it can see that the actual class of MyInterface1 given to MyInterface2 is MyClass, and that is what is returned from returnInstanceOfMyClass.
How to do that?
You need a second generic parameter:
public interface MyInterface2<U estends MyAbstractClass, T extends MyInterface1<U>> {
U returnInstanceOfMyClass();
}
I have an interface that ensures objects can make copies of themselves:
public interface Duplicable<T extends Duplicable<T>> {
public T duplicate();
}
I now have
class X implements Duplicable<X>
but I also have a class Y that extends X.
This isn't a problem, until I need another generic class:
public class DoStuffWithDuplicable<T extends Duplicable<T>>
I can't use a generic version of DoStuffWithDuplicable using Y, since it does not implement Duplicable<Y> but Duplicable<X> since it inherits it from X.
So I tried
public class DoStuffWithDuplicable<T extends Duplicable<? super T>>
.. but this means later introducing an unsafe cast
(T) obj.duplicate()
in the code body. Also the class parameters are more convoluted and the usage of the class harder to understand. Any ideas how to get around this problem?
I may not have understood your question properly, but I'll give it a go.
First of all, why do you have an interface that extends itself like that?
What you can try is this:
public interface Duplicable<T> {
public T duplicate();
}
Then when you use another class where you want the generic parameter to be Duplicable, you do it like this:
public class X<T extends Duplicable<T>> {
code...
}
Now when you inherit from X, any generic component in the subclasses will have to be Duplicable.
It is not possible to do this in Java.
Assume you call obj.duplicate() on an object of type Y. Then the typesystem can only ensure that it will return an object of type X, since Y implements Duplicate<X>.
But you can just create a DoStuffWithDuplicable<X> and pass Y objects to it.
DoStuffWithDuplicable<X> blub = new DoStuffWithDuplicable<X>();
Y y = (Y) blub.doStuff(new Y());
For return values, the client of your library can just use safe casts, as he probably knows the concrete types.
An other option would be to use unsafe casts in the library and check the types manually:
class DoStuffWithDuplicable<T extends Duplicable<? super T>> {
T doStuff(T obj) {
#SuppressWarnings("unchecked")
T t = (T) obj.duplicate();
if (!t.getClass().equals(obj.getClass()))
throw new ClassCastException("...");
return t;
}
}
I have written a class which is a base class of Class A and implements an interface of Class B.
Now my compiler is giving a wierd kind of error saying that "The return types of functiona from Class A is not compatible with return type of functiona in class B."
My Code is as below,
public class X extends A implements B
{
}
public class A
{
public Enumeration<String> test(){}
}
public interface B
{
public Enumeration<Object> test();
}
Now I can't understand why the compiler is giving such an error since already String is a type of an object, so what i understood is that automatic type conversion should happen in runtime because of that. Am i right? or my conceptual understanding has gone wierd on me?
If you can change the definition of the interface, you can broaden it and get what you want. The return type would be Enumeration<? extends Object>
What you're trying to do is possible in Java. As Ernest stated, an Enumeration is not a subclass of Enumeration, since Java genercis lacks the concept of variance.
Anyway, you can express you intention using type wildcard. You have to change you interface this way:
public interface B
{
public Enumeration<?> test();
}
Now your code compile fine. Just to let you know, you can also restrict your interface to some other type than Object. For example, if you have to build an interface that return Enumerations
of Number:
class X extends A implements B
{
}
class A
{
public Enumeration<Long> test(){return null;}
}
class C
{
public Enumeration<String> test(){return null;}
}
//This doesn't compile! String does not extend Number
/*class Y extends C implements B
{
}*/
interface B
{
public Enumeration<? extends Number> test();
}
String is a subclass of Object, but Enumeration<String> is not a subclass of Enumeration<Object>. If it were, then I could cast an Enumeration<String> to an Enumeration<Object>, then cast it to an Enumeration<Integer>, all without a warning; but when I tried to use it as an Enumeration<Integer>, I'd get ClassCastExceptions.
Note that Java arrays behave as I've described above, and this is widely considered a significant flaw in the design of the language.
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?