Enum<? extends interface> - java

I'm attempting to have a collection of enums that extend a common interface, so something like:
interface Fooable
{
void someCommonMethod();
}
enum E1 implements Fooable
{
// some enumuerations and a definition for someCommonMethod()
}
enum E2 implements Fooable
{
// some different enumerations and a different definition for someCommonMethod()
}
and then make use of this elsewhere by enforcing both that a variable is a Enum and implements the interface. So something along the lines of..
bar(Enum<? extends Fooable> fe)
{
fe.ordinal();
fe.someCommonMethod();
}
However, so far I seem to have to cast fe in order to treat it as implementing the interface, i.e.,
bar(Enum<? extends Fooable> fe)
{
fe.ordinal();
((Fooable)fe).someCommonMethod();
}
and while this should be safe... it seems suboptimal and that I may be overlooking something. Of course if I try to just pass the param as a Fooable then I wind up casting to treat it as a Enum and not only is this no-gain I'm now not even safe. See following:
bar(Fooable fe)
{
// potentially unsafe cast!
((Enum<?>)fe).ordinal();
fe.someCommonMethod();
}
Is there anything I'm overlooking or is the
Enum<? extends Fooable>
about as close to a 'good' solution as I'll get?
I am relatively new to Java and am still catching myself trying to use it like C or C++ so if I'm treating it like a hammer instead of a saw or overlooking something stupidly simple feel free to point it out :)

This means that T extends Enum and implements Fooable:
<T extends Enum<T> & Fooable>
Thus your method can be written as:
<T extends Enum<T> & Fooable> void bar(T fe) {
fe.ordinal();
fe.someCommonMethod();
}

One option you have is to add any of the methods from Enum you need onto Fooable or create a new interface that extends Fooable and adds the Enum methods you need.
Example:
interface Fooable {
void someCommonMethod();
}
interface FooableEnum extends Fooable {
int ordinal();
}
enum E1 implements FooableEnum {
// Implement someCommonMethod.
// ordinal() is already implemented by default.
}
Once you've done this you can use FooableEnum as the parameter type in your method signature and not worry about any of the generic stuff.

Related

How can I invoke name() inside an interface for an Enum?

I defined an interface for enum types.
interface MyInterface<E extends Enum<E> & MyInterface<E>> {
}
// e.g.
enum MyEnum implements MyInterface<MyEnum> {
}
Now I want to access name() method from a method defined in above interface.
interface MyInterface<E extends Enum<E> & MyInterface<E>> {
default void doSomeWithEnumName() {
// How can I access #name() method in here?
}
}
You can cast this to an Enum<?> and just access name().
System.out.println(((Enum<?>) this).name());
However, with the current set up, it is in fact possible for one to be naughty and create a non-enum class that implements your interface:
enum Bar implements MyInterface<Bar> {}
class Foo implements MyInterface<Bar> {}
Therefore, I would advise that you check the type of this first:
if (this instanceof Enum<?> enumThis) {
System.out.println(enumThis.name());
} else {
throw new RuntimeException("Only enums can implement this interface!");
}
(I can't think of how you would limit the interface to be only implementable only for enums - there are no "self" types in Java)

An interface has two type parameters. Can I implement the interface with the two types being the same, such that they are then compatible?

This is an existing interface:
public interface MyInterface<T, U> {
public T foo(U u);
}
I want to implement this interface under the assumption that T and U are the same type. I thought maybe I could leave the type parameters in as they are, and then as long as I only ever instantiate this particular implementation with two of the same type, that it might work:
public class MyOuterClass<A> {
public class MyClass<T, U> implements MyInterface<T, U> {
#Override
public T foo(U u) {
return u; //error here
}
//even though in the only instantiation of MyClass, T and U are the same
private MyClass<A, A> myInstance = new MyClass<A, A>();
}
But, perhaps unsurprisingly, this doesn't work, as types T and U are incompatible.
So then I thought maybe I could change MyClass to specify that its types would always be the same, by changing it to something like MyClass<A, A> implements MyInterface<A, A> or similar, but I get errors saying that T is already defined.
Is there a way to implement MyClass so that its two types will be the same?
(I'm more of a C++ guy than Java, so sorry if I'm missing something fundamental about Java's generic's here.)
Your myclass needs to look like this:
public class MyClass<T> implements MyInterface<T, T> {
#Override
public T foo(T in) {
return in;
}
}
Let's review what your suggested class definition does:
public class MyClass<T, U> implements MyInterface<T, U>
In this code, T and U do two things each:
in the first occurance they define a type variable of your MyClass class
in the second occurance they specify the concrete type of the MyInterface class
Since inside the body of your class T and U are unbounded type variables (i.e. nothing is known about the actual types), they are assumed to be incompatible.
By having only a single type variable in your MyClass you make your assumption explicit: there's only a single type, and I'm using it for both types of the interface.
Last but not least: remember that the compilation of a type is complete once the source is fully handled. In other words: contrary to what C++ does, "instantiation" of a generic type ("template type" or similar in C++; Sorry for my rusty terminology) does not handle. MyClass<Foo> and MyClass<Bar> are the same type, as far as the JVM is concerned (only the compiler actually distinguishes them).
Define a single type parameter for MyClass:
class MyOuterClass<A> {
public class MyClass<T> implements MyInterface<T, T> {
public T foo(T u) {
return u;
}
}
// Need only one 'A' here.
private MyClass<A> myInstance = new MyClass<A>();
}
When you say
public class MyClass<T> implements MyInterface<T, T> {
... you are defining one generic variable for MyClass and you are saying that it fulfills both the roles T and U in MyInterface.

Enforcing return type for an class that implements an interface

How do I enforce that the method getFoo() in the implementing class, returns a list of the type of same implementing class.
public interface Bar{
....
List<? extends Bar> getFoo();
}
Right now a class that implements Bar returns objects of any class that implements Bar. I want to make it stricter so that the class that implements Bar returns a List of objects of only its type in getFoo().
Unfortunately this cannot be enforced by Java's type system.
You can get pretty close, though, by using:
public interface Bar<T extends Bar<T>> {
List<T> getFoo();
}
And then your implementing classes can implement it like so:
public class SomeSpecificBar implements Bar<SomeSpecificBar> {
// Compiler will enforce the type here
#Override
public List<SomeSpecificBar> getFoo() {
// ...
}
}
But nothing stops another class from doing this:
public class EvilBar implements Bar<SomeSpecificBar> {
// The compiler's perfectly OK with this
#Override
public List<SomeSpecificBar> getFoo() {
// ...
}
}
This is not possible in Java, but you might wonder what the use-case is to force this in the interface.
If you program against the interface (which you typically do, why else define the interface) the type wouldn't be known
If you program against a specific class, this thread already provided options on how you can implement that specific class to return a List<itself>. And since you program against that specific class, the compiler has access to that specific return type and knows about it
The interface Bar<T extends Bar<T>> answers already here are right, but I just wanted to add that if this is really something you want to enforce, you may want to look at composing your objects rather than using inheritance. Without knowing too much about your classes, it might look something like this:
public interface FooGetter<T> {
List<? extends T> getFoo();
}
public class FooComposer<T extends Bar> {
...
final T bar;
final FooGetter<T> barGetter;
}
Or it could look very different... but the main point is that if you want the two Ts to match, composition may be the answer.
Of course, even that can be circumvented using raw types... but then again, if someone does that, they're just using a raw List, and when they get ClassCastExceptions you can safely hit them. :)
You should infer the generic on Bar:
public interface Bar<T extends Foo> {
...
List<T> getFoo();
}
You can just parameterize the method, but that will not ensure that the return type matches that of the class.
Maybe sth like this
public interface Bar {
....
List<? extends Bar> getFoo();
}
public class T implements Bar {
List<T> getFoo();
}
public class TestClass extends T {};
I liked yshavit answer best but I could not understand the code.
So I will try to write the code as I think it should be.
interface Bar
{
// stuff
// don't bother with the getFoo method
}
interface BarUtils
{
< T extends Bar > List < ? extends T > getFoo ( T bar ) ;
}
How about this:
interface Bar
{
// everything but getFoo ( ) ;
}
interface FooGetter < T >
{
List < ? extends T > getFoo ( ) ;
}
interface BarRef < T extends Bar & FooGetter < T > >
{
T get ( ) ;
}
anything that implements BarRef must implement T and anything that implements T must have the appropriately enforced getFoo method.

problem with wildcards and one class which implements two interfaces

I have this question.
I have class UserImpl implements MyUser, YourUser
and class UsersGetterImpl implements MyUsersGetter, YourUsersGetter.
I want to implement a method inside UsersGetterImpl, which returns
List<MyUser> getUsers() for MyUsersGetterinterface, and
List<YourUser> getUsers() for YourUsersGetterinterface, but I cannot understand what have to be the return type of getUsers() inside the UsersGetterImpl class - probably it has to be something with wildcards (like List<? extends UserImpl> getUsers(), but not exactly, because this example won't work...)
It is hard to tell what you are asking, but according to the Java Language Specification:
In a situation such as this:
interface Fish { int getNumberOfScales(); }
interface StringBass { double getNumberOfScales(); }
class Bass implements Fish, StringBass {
// This declaration cannot be correct, no matter what type is used.
public ??? getNumberOfScales() { return 91; }
}
It is impossible to declare a method named getNumberOfScales with the same signature and return type as those of both the methods declared in interface Fish and in interface StringBass, because a class can have only one method with a given signature (ยง8.4). Therefore, it is impossible for a single class to implement both interface Fish and interface StringBass.
However, if both of your interfaces specify the same return type, then you can go ahead and implement that method. If MyUser and YourUser have a common ancestor then you could do List<? extends User> or if they have no commonality you can use simply use List<?>.
At that point though, you have to stop and consider if a common implementation is what you actually want. I suspect there may be a more elegant solution, if you provided us with more details about your problem.
Edit:
Based on your comment, you want something like...
interface MyUserGetter { List<? extends MyUser> getUsers(); }
interface YourUserGetter { List<? extends YourUser> getUsers(); }
class UserGetterImpl { List<? extends UserImpl> getUsers(); }
This is untested, and I'd guess has a 50% chance of working.
The architectural suggestion is that instead of having a single implementation for two interfaces you might actually want two implementations of one interface:
interface User {}
class MyUser implements User {}
class YourUser implements User {}
interface UserGetter { List<? extends User> getUsers(); }
The short answer is: it can't be done. You cannot have two methods whose signature differs only by return type, and you therefore cannot have one class implement two interfaces that define methods that only differ by return type.
The easy fix is to make MyUsersGetter and YourUsersGetter have methods with different names.
One possible workaround would be to have UsersGetterImpl not implement MyUsersGetter and YourUsersGetter directly, but to have delegates:
class UsersGetterImpl {
public MyUsersGetter getMyUsers () {
return new MyUsersGetter () {
public List<MyUsers> getUsers () {
//do stuff here
}
}
}

java iterator/iterable subinterface

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.

Categories

Resources