I am calling a specific class using only its interface. The problem is, the class itself implements Comparable, but because I am referring to the class via a different interface, the compiler does not know it implements Comparable. I'm sure there is an easy solution to this... but I just can't think of it right now.
Will everything that implements the interface also implement Comparable<T>? If so, I suggest you just make the interface extend Comparable<T>.
Otherwise, you could just cast to Comparable<T> if you happen to know that in this case it will work. Of course, that loses some compile-time type safety, but that's the nature of the beast.
This seems odd to me... if you have main like the following, you can make it work with the Parent interface and Child classes below... but there is an oddity in that you could try to compare a ChildA to a ChildB which probably doesn't make sense to do.
Maybe if you gave us a hint at what the classes/interface are doing we could give a better answer.
public class Main
{
public static void main(final String[] argv)
{
Parent x;
Parent y;
x = new ChildA();
y = new ChildA();
x.compareTo(y);
}
}
abstract interface Parent
extends Comparable<Parent>
{
}
class ChildA
implements Parent
{
public int compareTo(Parent o)
{
throw new UnsupportedOperationException("Not supported yet.");
}
}
class ChildB
implements Parent
{
public int compareTo(Parent o)
{
throw new UnsupportedOperationException("Not supported yet.");
}
}
I'd suggest you to use Comapartor instead. You can use sort(list, Comparator). Your comparator implementation will cast class to Comparable and use its compare method. So the compiler will be satisfied and you will reuse the existing implementation of compare method.
You can do some freaky generics. Let's say the main interface is Lickable (which defines a method lick()), and you want a method that will process objects which are Lickable and Comparable. You write:
public <LickableAndComparable extends Lickable & Comparable<LickableAndComparable>> void lickGreater(LickableAndComparable a, LickableAndComparable b) {
if (a.compareTo(b) > 0) a.lick();
else b.lick();
}
You can then call that with objects of any type which is both Lickable and Comparable. Note that it only works if both arguments share a type which is both Lickable and Comparable to itself. If you only have one class in mind, then this should be fine. You may run into migraine-inducing compiler errors if your usage of the method gets complicated.
Comparable interfaces are tricky. In general, if you mark an interface as Comparable to itself, any correct implementation may only use methods from this interface to perform the comparison. Otherwise this relation can't be made anti-symmetric - a necessary condition to have a consistent ordering.
So think twice before marking an interface as comparable.
There is however a workaround in your case, if you are sure you are not mixing different implementations of your interface:
interface Foo {
}
interface Bar extends Foo, Comparable<Bar> {
}
class FooComparator<T extends Foo & Comparable<T>> implements Comparator<T> {
#Override
public int compare(T arg0, T arg1) {
return arg0.compareTo(arg1);
}
}
Related
How can i make an interface in java with a function that accepts a parameter of the type that extends the interface?
For example take the interface ISelfComparable
if class A extends it then i would expect it to implement
bool compareTo(A other)
but if class B extends it then i would expect it to implement
bool compareTo(B other)
I know i can use a generic interface but it seems incorrect because it doesn't make any sense for A to extend ISelfComparable<B>
If this is impossible, what is the best practice in this kind of situation?
The usual solution is self-bounded generics, as seen in the Enum class.
interface Example<T extends Example<T>> {
void foo(T t);
}
public class ExampleImpl implements Example<ExampleImpl> {
#Override
public void foo(ExampleImpl example) {
}
}
How it works is a bit dizzying, but is explained very well here for example. There is also a very good answer on the subject here.
Note that it isn't foolproof, as it allows this:
public class ExampleImpl2 extends Example<ExampleImpl {
#Override
public void foo(ExampleImpl example) {
}
}
But in practice the self-bounded idiom is used to express exactly the sort of thing you're after.
If you really, really, really need the parameter object to always be the exact same class as this, you have to do a runtime check. (It also raises the question of why you need this, but that would take us way off topic.)
Have a look at the class java.lang.Comparable: it has an argument with the type of the objects that can be used int compareTo.
By analogy:
public interface ISelfComparable<T extends ISelfComparable<T>> {
boolean compareTo(T other);
}
There is a way to check the type of parameter but only in runtime. For example you can implement type checking in default method:
interface ISelfComparable {
default boolean compareTo(ISelfComparable param) {
if (this.getClass() != param.getClass()) {
throw new IllegalArgumentException();
}
...
}
}
Then each implementation of this interface should look like this:
class A implements ISelfComparable {
#Override
public boolean compareTo(ISelfComparable param) {
ISelfComparable.super.compareTo(param);
...
}
}
In this case if you call new A().compareTo(new B()); then java.lang.IllegalArgumentException will be thrown
Interfaces like Comparable<> use generics to establish which type a class is comparable to. In some cases, it may make sense to have one class comparable to another such as A implements Comparable<B>. But I'm working through a situation now where I would like the interface to specify that the return type is always the same as the type implementing the interface. That is to say, the type of A.get() should always be A.
My original attempt to force self-reference looked like:
interface Property<T extends Property<T>> {
public T get();
}
This allows
class A implements Property<A> {
public A get() { ... }
}
while preventing things like
class A implements Property<B> {
public B get() { ... }
}
Unfortunately, it allows the following to compile:
class A implements Property<A> {
public A get() { ... }
}
class B implements Property<A> {
public A get() { ... }
}
Is there a way to do this?
No, there is no way to force a subclass to narrow a return type on an inherited method based on the generic type parameter of the Curiously Recurring Template Pattern. You cannot force B to have get() return B. It's an object-oriented principle that a subclass can inherit a method without changing anything about it.
Sometimes I've wished for this feature -- a generic "relationship to self" type. Here's how I would have the syntax. The keyword "this" would represent this type - A in A, B in B.
public class A {
public this get() {
return this; // Or another instance of this type
}
}
public class B extends A {
// "this" on get in A forces B to override "get"
// to narrow the return type
#Override
public this get() {
return this;
}
}
But forcing B to override getA() goes against object-oriented principles. The subclass should be free to inherit a method from a superclass as-is.
I know this isn't a good question to ask and I might get cursed to ask it but I cannot find any place to get help on this question
Below is a Generic class that appeared in my interview question (which I have already failed). The question was to tell what this Class declaration is doing and in what circumstances this could be used for ?
I have very limited understanding of Generic programming but I understand that 'T' is Type and 'extends' here means that the Type should have inherited 'SimpleGenericClass' but I do not understand the '?' at the end and in what circumstances this Class could be potentially used for
public abstract class SimpleGenericClass<T extends SimpleGenericClass<?>> {
}
First, because the class SimpleGenericClass is abstract, it is meant to be subclassed.
Second, it is a generic class which means that inside the class somewhere you will almost assuredly be using the generic parameter T as the type of a field.
public abstract class SimpleGenericClass<T...> {
T x;
}
Now the first interesting thing here is that T is bounded. Because it is declared as T extends SimpleGenericClass<?> it can only be SimpleGenericClass<?> or some subclass of SimpleGenericClass<?>. You also asked about thr ?. That's known as a wildcard and there is a pretty good explanation of it at the Java Tutorial on Wildcards. In your case we would say this is a "SimpleGenericClass of unknown." It is needed in Java because SimpleGenericClass<Object> is NOT the superclass of SimpleGenericClass<String>, for example.
The second interesting thing though is that since T is a SimpleGenericClass of some sort, your class is more than likely defining recursive structures. What comes to my mind are trees (think of expression trees) where SimpleGenericClass is the (abstract) node type, designed to be subclassed with all kinds of specialized node types.
UPDATE This SO question on self-bounded generics might be helpful to you.
UPDATE 2
I went ahead and put together some code that illustrates how this can be used. The app doesn't do anything but it does compile and it shows you how the generic bounds can supply some possibly-meaningful constraints.
public abstract class Node<T extends Node<?>> {
public abstract T[] getChildren();
}
class NumberNode extends Node {
int data;
public Node[] getChildren() {return new Node[]{};}
}
class IdentifierNode extends Node {
int data;
public Node[] getChildren() {return new Node[]{};}
}
class PlusNode extends Node {
NumberNode left;
NumberNode right;
public NumberNode[] getChildren() {return new NumberNode[]{};}
}
The nice thing here is that NumberNode[] is a valid return type for PlusNode.getChildren! Does that matter in practice? No idea, but it is pretty cool. :)
It's not the greatest example, but the question was rather open ended ("what might such a thing be used for?"). There are other ways to define trees, of course.
This really only means that you allow the user of class SimpleGenericClass to parametrize instances of the class with the type T. However, T cannot be any type, but must be a subtype of SampleGenericClass (or SampleGenericClass itself).
In the remainder of the code of class SimpleGenericClass you may use type T in method signatures.
Let's assume for a second that SimpleGenericClass is not abstract. When using it, you could then write:
new SimpleGenericClass<SampleGenericClass<String>>();
I.e. you parametrize SimpleGenericClass with SampleGenericClass and SampleGenericClass with String.
This basically sais: in this class you have a Type placeholder called T, and a restriction on that placeholder, it must be of type SimpleGenericClass or something that extends it. Once you obey that rule you can create instances of your class and give an actual type to T, that later on can be used in methods of that class, something like this:
public class C <T extends Number>{
public void doSomething(T t) {
}
public static void main(String... args) {
//works:
C<Number> c = new C<Number>();
c.doSomething(new Number() {
//Aonimous implementation of number
});
//won't work
//C<Object> c = new C<Object>();
C<Integer> c2 = new C<Integer>();
c2.doSomething(new Integer(1));
//won't work
//c2.doSomething(new Number() {
//Aonimous implementation of number
//});
}
}
The SimpleGenericClass<?> is pretty redundant at this point. If another generic type is needed on this class, you can have more than one (SimpleGenericClass<T extends SimpleGenericClass, T2 extends Whatever>)
By definition it says that the SimpleGenericClass can work on a type <T> which is subclass of SimpleGenericClass.
So I assume there will be some operations which will work on <T>.
Now to see why one would define a template like this - (not much I can think of , really ) may be a scenario where the SimpleGenericClass is an abstract class (just realized it is as per OP :P) and expects that it can work on any concrete classes ?
Guys what do you think ?
I guess you have got the question in this form (T instead of ?):
public abstract class SimpleGenericClass<T extends SimpleGenericClass<T>>
Take a look at this code:
abstract class Foo<SubClassOfFoo extends Foo<SubClassOfFoo>>
{
/** subclasses are forced to return themselves from this method */
public abstract SubClassOfFoo subclassAwareDeepCopy();
}
class Bar extends Foo<Bar> {
public Bar subclassAwareDeepCopy() {
Bar b = new Bar();
// ...
return b;
}
}
Bar b = new Bar();
Foo<Bar> f = b;
Bar b2 = b.subclassAwareDeepCopy();
Bar b3 = f.subclassAwareDeepCopy(); // no need to cast, return type is Bar
The trick going on with Foo<SubClassOfFoo extends Foo<SubClassOfFoo>> is:
Any subclass of Foo must supply a type argument to Foo.
That type argument must actually be a subclass of Foo.
Subclasses of Foo (like Bar) follow the idiom that the type
argument they supply to Foo is themselves.
Foo has a method that returns SubClassOfFoo. Combined
with the above idiom, this allows Foo to formulate a contract that
says “any subclass of me must implement subclassAwareDeepCopy() and
they must declare that it returns that actual subclass“.
To say that another way: this idiom allows a superclass (such as an Abstract Factory) to define methods whose argument types and return types are in terms of the subclass type, not the superclass type.
The trick is done for example in Enum JDK class:
public abstract class Enum<E extends Enum<E>>
Refer here for more details.
Is there a way in java to specify, that the type parameter of a generic class must be an interface (not just extending it!)
What I want to do is the following:
public class MyClass<X extends SomeInterface, Y extends SomeOtherClass & X>
Meaning that Y must be a subclass of SomeOtherClass AND implement X.
What I currently get by the compiler is
The type X is not an interface; it cannot be specified as a bounded parameter
So, how can I tell the compiler that X must always be an interface?
Edit:
OK, I guess I oversimplified my problem a bit. Let's use my actual application domain to make it more clear:
I have an API for representing diagrams. A Diagram contains Node and Edge objects. All these three classes implement the Shape interface. Shapes may have child shapes, a parent shape and belong to a diagram.
The thing is, that I need to make two versions of this API: one open-source with just basic functionality and an extended one with more features. However, the extended API must only provide methods, which return the extended types (ExtendedDiagram, ExtendedNode, ExtendedEdge and (here comes the problem) ExtendedShape).
So I have something like this:
/* BASIC CLASSES */
public interface Shape<X extends Shape<X,Y>, Y extends Diagram<X,Y>>{
public List<X> getChildShapes();
public X getParent();
public Y getDiagram();
...
}
public class Diagram<X extends Shape<X,Y>, Y extends Diagram<X,Y>> implements Shape<X,Y>{...}
public class Edge<X extends Shape<X,Y>, Y extends Diagram<X,Y>> implements Shape<X,Y>{...}
...
/* EXTENDED CLASSES */
public interface ExtendedShape extends Shape<ExtendedShape,ExtendedDiagram> { ... }
public class ExtendedDiagram extends Diagram<ExtendedShape,ExtenedDiagram> implements ExtendedShape { ... }
public class ExtendedEdge extends Edge<ExtendedShape,ExtenedDiagram> implements ExtendedShape { ... }
...
The extended API works fine and the basic API code gives some warnings, but the main problem occurs when using the basic API:
public class SomeImporter<X extends Shape<X,Y>, Y extends Diagram<X,Y>, E extends Edge<X,Y>>{
private Y diagram;
public void addNewEdge(E newEdge){
diagram.addChildShape(newEdge);
...
That last line gives me the following warning:
The method addChildShape(X) in the type Diagram is not applicable for the arguments (E)
So now, I would just like to specify that E also needs to implement X and all would be fine - I hope ;)
Does all that make sense? Do you guys know a way to do that? Or is there even a better way to get the extended API with the said restrictions?
Thanks for sticking with me, any help is greatly appreciated!
You can use:
class Foo<T extends Number & Comparable> {...}
A class Foo with one type parameter, T. Foo must be instantiated with a type that is a subtype of Number and that implements Comparable.
In the generics context, <Type extends IInterface> handles both extends and implements. Here's an example:
public class GenericsTest<S extends Runnable> {
public static void main(String[] args) {
GenericsTest<GT> t = new GenericsTest<GT>();
GenericsTest<GT2> t2 = new GenericsTest<GT>();
}
}
class GT implements Runnable{
public void run() {
}
}
class GT2 {
}
GenericsTest will accept GT because it implements Runnable. GT2 does not, therefore it fails when trying to compile that second GenericsTest instantiation.
Maybe you can simplify your model a bit: too much generics become quickly a real pain in terms of readability, and that's quite an issue if you define a public API. Usually, if you can't understand anymore what should be inside the brackets, then you're going too far for your need - and you can't expect users to understand it better than yourself...
Anyway, in order to make your code compile, you may try defining something like this, in the Shape type:
public <S extends Shape<?,?>> void addChildShape(S shape);
That should do it.
HTH
You wrote the following:
public interface Shape<X extends Shape<X,Y>, Y extends Diagram<X,Y>>{
public List<X> getChildShapes();
public X getParent();
public Y getDiagram();
...
}
I would advise, at the minimum, getting rid of the X type variable, as follows:
public interface Shape<Y>{
public List<Shape<Y>> getChildShapes();
public Shape<Y> getParent();
public Diagram<Y> getDiagram();
...
}
The reason being is that what you originally wrote suffers from a potentially unbounded recursive nesting of the type parameters. A shape may be nested within a parent shape, which may be nested within another, all of which must be accounted for in the type signature... not a good recipe for readability. Well, it doesn't happen quite that way in your example, in which you declare "Shape<X>" instead of "Shape<Shape<X>>" but that's the direction you're going in, if you ever wanted to actually use Shape on its own...
I would probably also recommend going one step further and getting rid of the Y variable for similar reasons. Java generics don't cope very well with this sort of composition. When attempting to enforce static types for this type of modelling via generics, I've found that the type system starts to break down when you start to extend things later on.
It's typical of the Animal/Dog problem... Animal has a getChildren(), but Dog's children must also be Dogs... Java doesn't cope with this well because (in part due to the lack of abstract types as in languages like Scala, but I'm not saying you should rush off and use Scala for this problem either) the type variables have to start being declared in all sorts of places where they don't really belong.
Use a pre-processor to generate the "reduced" version of your code. Using apt and annotations might be a nice way to do it.
I might be WAY off base here, but my understanding of generics is a little different.
I am asking someone to correct me if I am wrong.
IMO -
This is a very confusing structure that you have. You have SubClasses of Shape being referenced infinitely it looks like.
Your Shape interface is utilized in the same manner as a HashMap, but I have never seen a HashMap do what you are trying to do, eventually you have to have X be a class in Shape. Otherwise you are doing HashMap
If you always want X to be a "IS A" relationship to an interface it won't happen. That is not what generics are for. Generics are used to apply methods to multiple Objects, and interfaces cannot be Objects. Interfaces define a contract between a client and a class. All you can do with the is say that you will accept any Object that implements Runnable, because all or some of your methods are required to utilize the Runnable interface methods. Otherwise if you don't specify and you define as , then your contract between your class with the client can produce unexpected behavior and cause either the wrong return value or an exception to be thrown.
For example:
public interface Animal {
void eat();
void speak();
}
public interface Dog extends Animal {
void scratch();
void sniff();
}
public interface Cat extends Animal {
void sleep();
void stretch();
}
public GoldenRetriever implements Dog {
public GoldenRetriever() { }
void eat() {
System.out.println("I like my Kibbles!");
}
void speak() {
System.out.println("Rufff!");
}
void scratch() {
System.out.println("I hate this collar.");
}
void sniff() {
System.out.println("Ummmm?");
}
}
public Tiger implements Cat {
public Tiger() { }
void eat() {
System.out.println("This meat is tasty.");
}
void speak() {
System.out.println("Roar!");
}
void sleep() {
System.out.println("Yawn.");
}
void stretch() {
System.out.println("Mmmmmm.");
}
}
Now if you did this class you can expect that you CAN always call 'speak()' & 'sniff()'
public class Kingdom<X extends Dog> {
public Kingdom(X dog) {
dog.toString();
dog.speak();
dog.sniff();
}
}
However, if you did this you CANNOT ALWAYS call 'speak()' & 'sniff()'
public class Kingdom<X> {
public Kingdom(X object) {
object.toString();
object.speak();
object.sniff();
}
}
CONCLUSION:
Generics give you the ability to utilize methods on a wide range of objects, not interfaces. Your final entry into a generic MUST be a type of Object.
The reserved word “extends” as along with a type parameter T is used to specify a bound.
‘…in this context, extends is used in a general sense to mean either "extends" (as in classes) or "implements" (as in interfaces).’
[ https://docs.oracle.com/javase/tutorial/java/generics/bounded.html ]
In short, “extends” can only be used to specify a bound (whether a class or an interface) for some class type parameter T and not any interface type parameter T.
In your case,
public class MyClass<X extends SomeInterface, Y extends SomeOtherClass & X>
The compiler resolves X to be a class. For the second occurrence of X along with the type parameter Y (which clearly needs to be a class anyway), it requires X to be an interface. Since it has already resolved X to be class, it signals the error for the second occurrence of X,
The type X is not an interface;
Further, had X been specified in the first occurrence as an unbounded parameter, the compiler would have resolved it to be either a class or an interface and it would’ve considered the second occurrence of X to be a possible interface and thus allowed compilation. Since it was not so, the compiler clarifies,
it cannot be specified as a bounded parameter
I have an interface for a variety of classes, all of which should implement Iterator, so I have something like
public interface A extends Iterable<A> { ...otherMethods()... }
For the concrete classes, however, this means I must use
public class B implements A { public Iterator<A> iterator() {...} }
when I'd prefer (or at least, think I'd prefer) to use public Iterator<B> iterator() {...} so that concrete use of the class could have the explicit type (in case I wanted methods that weren't in the interface to be available, or some such. Maybe that should never come up? Or it's poor design if it does?
The flipside is that using the Iterator interface
public interface A extends Iterator<A> { ...otherMethods()... }
the concrete classes compile just fine with
public class B implements A { public B next() {...} }
What gives?
Carl was right, my first answer didn't compile but this seems to. Not sure if it's what you want exactly.
public interface A<T extends A> extends Iterable<T> {
}
public class B implements A<B> {
#Override
public Iterator<B> iterator() {
return null;
}
The concrete class compiles fine because B extends A, and since Java 5 a return type on a subclass can be a subclass of the return type on the superclass.
As for the generic, I have hit the same wall, and you have two options that I know of.
One is to paramaterize A:
public interface A<T extends A> extends Iterable<T>
then:
public class B implements A<B>
However, that has a disadvantage that you will need to give a parameter of A, instead of having it fixed, even if you want A:
private class NoOneSees implements A<A>
As to the question of if you actually want Iterator<B>, in the case of an Iterable, most likely that is preferable, and considering that these are interfaces, the need to redeclare the parameter is probably reasonable. It gets a little more complicated if you start inheriting concrete classes, and for things that have meaning other than an Iterable, where you may want covariance. For example:
public interface Blah<T> {
void blah(T param);
}
public class Super implements Blah<Super> {
public void blah(Super param) {}
}
public class Sub extends Super {
public void blah(Super param) {}
//Here you have to go with Super because Super is not paramaterized
//to allow a Sub here and still be overriding the method.
}
Similarly for covariance, you can't declare a variable of type Iterator<A> and then assign an Iterator<B> in it, even if B extends A.
The other option is live with the fact that further implementation/subclasses will still reference A.
The other answers have the right gist - but you'll get the right mechanics by declaring the generic type as
A<T extends A<T>>
This forces a class to return an iterator that is of its own type or lower - so you would be able to declare
class B implements A<B>
but not
class B implements A<A>
which I suspect is closer to what you want (i.e. implementations must return iterators over themselves, rather than simply over As).
Note that your experiences with Iterator vs Iterable stem from the lack of covariance of generic types; an instance of B is an A, but an Iterator<B> is not an Iterator<A>.
I guess this is what you want:
public interface A<T extends A<?>> extends Iterable<T>
public class B implements A<B> {
public Iterator<B> iterator() {...}
}
Your design decisions are your own, but I can't think of any reason for EVERY class in a design to implement Iterable. There must be some kind of thing that is contained in a collection but isn't actually a collection itself. I would take a long hard look at the fundamental design. Maybe some iterables will want to return iterators of things that are not related to themselves.