Enforcing the implementer of an interface to be an enum - java

I would like to store a type called App inside a set. App needs to be an enum that implements the App interface.
Set<App> myApps;
I have defined the interface like so...
interface App<T extends Enum<T>> {}
This is almost working, for example, you cannot do this...
class MyClass implements Application<MyClass> {}
However, you can do this...
enum MyEnum implements Application<MyEnum> {}
class Myclass implements Application<MyEnum> {}
Which is wrong. I only want enums to be able to implement this interface, how can I enforce this?

Define a method that allows you to add Elements into the set, BUT use a constraint for that parameter...
public <E extends Enum<E> & IMyInterface> void addToSet(final E value) { }
now after that
addToSet(MyEnum.K) will compile
but
addToSet(new Myclass()) will NOT compile

AFAIK it is not possible to enforce an implementor of an interface to have certain properties such as being an enum.
However, depending on your code and how you use that interface you can make it hard for someone not to make the implementor an enum:
Require T to implement App<T> as well to prevent passing any enum to the class declaration (i.e. App<T extends Enum<T> & App<T>>)
Use additional boundaries when possible (see ΦXocę 웃 Пepeúpa's answer)
Add methods that are already implemented by Enum such as name(), ordinal(), getDeclaringClass() etc.
Let App<T ...> extend Comparable<T>.
When possible call getClass().isEnum() to check that property at runtime. This is not ideal but there are similar solution's that are commonly used such as Collections.unmodifiableSet().

Related

Java inheritance hierarchy -- implementing an interface a super-class is implementing

When I extend a class, say class A in class B, i'm implementing all interfaces that class A implements.
In the following,
interface INTF { ... }
class A implements INTF { ... }
class B extends A { .... }
class B, being a descendant of class A, is implementing INTF.
So, what's my gain in declaring class B as
class B extends A implements INTF { .... }
?
//===========================
EDIT:
Java APIs are doing this. Eg.:
public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V> { ...
what for ?
TIA
There is no difference if your sub class restates that it implements an interface.But there is a huge gain when it comes to Reflection API.I have personally faced it..
When you call B.class.getInterfaces() ,it returns a Class[] containing only those interfaces explicitly declared by the class and not its superclasses,although in reality it is implementing interfaces which are implemented by its superclasses.
To solve it,you need to recursively call the super class and get all the interfaces implemented.Declaring an interface explicitly in your sub class will help you in this case
You don't have to re-declare the interface again. However, there will be differences if you using Java reflections - B.class.getInterfaces().
If you don't re-declare the interface again. B.class.getInterfaces() -- return zero interface
If you re-declare the interface B.class.getInterfaces() - Return one interface
So deciding to re-declare the interface again or Not depending on how you use java reflections on it. For most case, we don't re-declare it again.
You don't have to specify the interface again. You could specify all the implemented methods again, but you don't have to do that either.
If A changes the interface it implements in future B might not need to know about it.
It makes no difference whether you specify that B implements INTF or not, since it must implement it anyway, since A is implementing it.
I'm not sure why Java APIs are doing it. I'm assuming they simply want to make it more clear to the user of LinkedHashMap that it implements Map (otherwise the user would have to look at the declaration of HashMap to find this out).

Force Interface Method Return Value to be Wildcard with Multiple Classes

This question is a follow up from Java Generics Wildcarding With Multiple Classes.
I'm writing an interface like this:
public interface SomeInterface {
public Class<? extends SomeClass implements OtherInterface> getClassForObject(Object object);
}
I know that this is wrong syntax, as is Class<? extends SomeClass & OtherInterface>, and it seems all options.
I can't have the interface do what was suggested in the answer to the question linked above (public interface SomeInterface<T extends SomeClass & OtherInterface>) because implementations of this interface might want to return different things for different inputs.
I also can't create an abstract class that extends SomeClass and implements OtherInterface and have everything extend from that because there are many existing implementations of SomeClass that clients may want to extend from.
Is there any way to force implementations of this interface to return a type that fits both constraints? Besides throwing a runtime exception somewhere else in the code?
You cannot impose multiple restrictions on a wildcard. You can declare a generic type parameter on the method instead of the interface itself, and you can impose multiple restrictions on it. Try:
public interface SomeInterface {
public <T extends SomeClass & OtherInterface> Class<T>
getClassForObject(Object object);
}

How can an interface include a method that references the concrete implementation type of the interface in its signature or return type?

Suppose I am designing something like the following interface:
public interface MyInterface{
public MyInterface method1();
public void method2(MyInterface mi);
}
However, there is the caveat that the return type for method1 and the parameter for method2 match the concrete implementation and not just MyInterface. That is, if I have MyInterfaceImpl that implements MyInterface, it needs to have the following:
public class MyInterfaceImpl implements MyInterface{
#Override
public MyInterfaceImpl method1(){...}
#Override
public void method2(MyInterfaceImpl mi){...}
}
As written above, method1 won't cause any compile errors, but there is nothing guaranteeing that the return type matches in all implementations. Of course method2 won't even compile because the signature does not match the interface.
One candidate solution is to use self-referential or recursive bounds in generics:
public interface MyInterface<T extends MyInterface<T>>{
public T method1();
public void method2(T mi);
}
public class MyInterfaceImpl implements MyInterface<MyInterfaceImpl>{
#Override
public MyInterfaceImpl method1();
#Override
public void method2(MyInterfaceImpl mi);
}
This would get me what I want with one exception: other implementations might pass the wrong generic type (nothing forces T to match the concrete type). So potentially someone else could implement the following:
public class NotMyInterfaceImpl implements MyInterface<MyInterfaceImpl>{
#Override
public MyInterfaceImpl method1();
#Override
public void method2(MyInterfaceImpl mi);
}
That would compile just fine even though NotMyInterfaceImpl should implement MyInterface<NotMyInterfaceImpl>.* That makes me think I need something else.
*Note that I don't think I'm trying to violate LSP; I'm OK with the return type/parameter being subclasses of NotMyInterfaceImpl.
So I don't know of a clean way to do this. That leads me to believe that I might be focusing too much on implementation details in the interface, but it doesn't seem that way to me. Is there any way to do the type of thing I described, or is this some kind of smell that I'm putting something in an interface that doesn't belong there?
This is the exact situation faced by the Comparable interface (its compareTo method wants to take an argument the same type as the object it is called on). So what does it do? It's simply defined as Comparable<T>. The idea is that an implementing class "should" implement Comparable with itself as the parameter (allowing it to "compare to" itself); but this is not enforced (since there is no way to do it).
Yes, as you noted, this will allow any class to implement Comparable with a parameter of any other class: class Foo implements Comparable<Bar> where Foo and Bar have no relation to each other. However, this is not really a problem.
All the methods and classes (sorting, maximum, etc.) that require Comparable objects have the following generic type constraint <T extends Comparable<? super T>>. This ensures that objects of type T are comparable with themselves. That way, it is completely type-safe. So the enforcement is not made in the declaration of the Comparable interface, but in the places that use it.
(I notice that you use <T extends MyInterface<T>> while Comparable uses simply <T>. Although <T extends MyInterface<T>> will exclude cases where the type parameter does not implement MyInterface, it will not exclude cases where the type parameter does implement MyInterface, but is different than the class. So what's the point of half-excluding some cases? If you adopt Comparable's way of restricting it where they are used, it's type-safe anyway, so there is no point in adding more restrictions.)
I believe that this cannot be done. There is simply no way to refer to an object's implementation class in the framework of generics, nor, as far as i know, any way to construct a cage out of pure generics which is capable of constraining the implementation class to match a type parameter.
The most useful thing i can suggest is using a self-referential parameter, and then always acquiring instances of implementations from factory methods which look like:
public <T extends MyInterface<T>> T newInstance();
It is easier for a camel to pass through the eye of a needle than for an instance of NotMyInterfaceImpl to pass through that return type. So, although troublemakers could write classes which do not conform to your masterplan, they couldn't return them from factories. Unless NotMyInterfaceImpl extended MyInterfaceImpl; but then, in a sense, it would also be a MyInterfaceImpl, so perhaps that would be kosher?
EDIT: A slightly more useful version of that idea is to always pass instances of implementations of the interface around in a suitably restrictive holder, like:
class Holder<T extends MyInterface<T>> {
public final T value;
}
If someone gives you a Holder<Q>, then you know that Q must be a version of MyInterface bound to itself, which is what you're after.
The point of returning the interface is such that the method does not care the actual implementation of the returned object. In your case you actually want to mandate the type to be a particular sub-implementation of that interface.
To apply the constraints that you described above, IMHO the design should probably be a base class instead of an interface. This allows you to control the implementation, for example a top-level flow, and leave low-level strategy to sub-classes to implement:
class MyBaseImpl {
public final void fixedFlow() {
MyBaseImpl obj = method1();
obj.method2(this);
}
protected abstract MyBaseImpl method1();
....
}
There has to be other methods to make it interesting...; perhaps you have good reasons to want to do this...
Hope this helps!
What you are trying to do is not legal because you are trying to narrow the parameter of the implemented type, and this "does not make sense". You are tryint to use "covariant" parameters, and only covariant return types are allowed (and even logic, and only supported from Java 5).
I mean, if it was possible to use covariant parameter types, you could do things like:
MyInterface instance = new MyInterfaceImpl();
And then, invoke on "instance" the method with another implementation supported by the interface but not supported by the MyInterfaceImpl class this way:
instance.method2(new MyInterfaceImpl_2());
Java cannot convert MyInterfaceImpl_2 to MyInterfaceImpl, so it prevents you from doing so at compilation time.
What you could do is to widen the parameter, using "contravariant" parameter, which would be logic. For more detail on this, check this anser:
Demonstrate covariance and contravariance in Java?
The only workaround that I can think of, is to solve the problem at runtime, I mean, doing something like this:
public class MyInterfaceImpl implements MyInterface{
#Override
public void method2(MyInterface mi){
realMethod((MyInterfaceImpl) mi);
}
public void realMethod(MyInterfaceImpl) {...}
}
But you could get ClassCast exception, of course.
Is this what you are looking for?
public interface MyInterface {
static abstract class MyInterfaceImpl implements MyInterface {
#Override
public abstract MyInterfaceImpl method1();
#Override
public abstract void method2(MyInterfaceImpl mi);
}
MyInterfaceImpl method1();
void method2(MyInterfaceImpl mi);
}
And you could even implement method 1 or 2 instead of making them abstract.

Java extend generically specified type

Is there anyway I could do something like this:
Class extends <T extends ClassB>
Can you have a class extend a class as long as that class extends the class that the generically specified class must extend?
What would be the syntax/structure for it?
No, that is not possible. I don't think it would make much sense either—when you use generics and specify a class this way, you only have the information from the class you specified.
For normal use (containers, for example), this makes sense because it lets you rely on a particular class or interface's methods while being able to ensure additional type safety. However, for extending a class, this would not really make much sense—since you can only rely on the methods of ClassB, it would be functionally identical to just doing Class extend ClassB.
For your idea to make much sense, you would need to be able to take the class you've defined and pass in a type to "extend". However, this would have many of the same pitfalls as multiple inheritance—what would you do if a method first defined in Class was also defined in the class you pass in to the generics, but not in ClassB? Not having multiple inheritance in Java was a design decision and having generics that work like that would go against that.
In short, something like this would either be like multiple inheritance or would be identical to normal inheritance.
I think that because of type erasure, you won't be able to do this. For instance, you can't even do this:
class A<T> {
class B extends T {
}
}

Being able to implement an interface only when the class inherit from a specific Class

I'm programming with java.
Let's say I have an "MyInterface" interface, and a "MyClass" abstract class.
I want to ensure that every class implementing the "MyInterface" interface is inherited from "MyClass".
An inherited class from MyClass is perfectly able to NOT implement the "MyInterface" interface.
Is this possible ? Thanks.
I'm sorry if my english is bad but I'm french.
I want to ensure that every class
implementing the "MyInterface"
interface is inherited from "MyClass".
Nope. That's not possible. The whole point of an interface is to make it so that classes from different inheritance hierarchies can implement support for a pre-defined set of capabilities.
AFAIK, you can't do this directly.
Generics let you say something like this, if it helps:
public <T extends MyClass & MyInterface> void foo(T param) { /**/ }
So, you can only call foo() with parameters that are both MyClass and MyInterface.
Or, why not have two abstract base classes?
abstract class MyClass { /* stuff here */ }
abstract class MyInterfaceClass extends MyClass { /* empty */ }
Then, use MyInterfaceClass instead of MyInterface.
Or, if you just care about containers, write your own:
static class MyList extends ArrayList<MyInterface> {
#Deprecated
public boolean add(MyInterface obj) {
assert obj instanceof MyClass;
return super.add(obj);
}
public <T extends MyClass & MyInterface> boolean add(T obj) {
return super.add(obj);
}
}
Then, you will get a deprecation warning any time you make a mistake.
But my question remains - what problem are you trying to solve? Can you use more descriptive names instead of "Class" and "Interface"? Perhaps the right solution is something completely different..
No, it is not possible. Any class can implement MyInterface. There is no way to limit implementors to subclasses of MyClass.
If you really need a limitation like that I think you'll be stuck with having to not use an interface and instead use MyClass in place of an interface.

Categories