A class implementing an interface that takes an enum - java

So, say I have a simple enum and a class that uses it:
enum ThingType { POTATO, BICYCLE };
class Thing {
public void setValueType(ThingType value) { ... }
public ThingType getValueType() { ... }
}
But, in reality, I have lots of different classes that implement setValueType, each with a different kind of enum. I want to make an interface that these classes can implement that supports setValueType and getValueType using generics:
interface ValueTypeable {
public Enum<?> getValueType(); // This works
public <T extends Enum<T>> setValueType(T value); // this fails horribly
}
I can't change the class model because the classes are auto-generated from an XML schema (JAXB). I feel like I'm not grasping enums and generics combined. The goal here is that I want to be able to allow a user to select from a list of enums (as I already know the type at runtime) and set the value in a particular class.
Thanks!

Have you tried parameterizing the interface itself. Like:
class Thing<E extends Enum<? extends E>> {
public E getValueType();
public void setValueType(E value);
}
Then you have the subclass extend the one with right type:
class SomeSubClass implements Thing<ThingType> { ... }

enums are for when you have a fixed set of them. When you say that each implementation has its own, then you no longer have a fixed set, and how you are trying to use enums doesn't match your needs.
You might be interested in the request for Java to be able to have abstract enums.

Related

Cumbersome generics declaration in a huge Java classes hierarchy

I have basically two types of each entity in my project which are distinguisched only by specifying the parent catalog type in the class generics declaration. Catalogs iteself are declared with generics as they can have links to a specific old catalog of the same type.
abstract class AbstractCatalog<T extends AbstractCatalog<T>> {
public abstract T getOld();
}
class Catalog1 extends AbstractCatalog<Catalog1> {
#Override
public Catalog1 getOld() { ... }
}
class Catalog2 extends AbstractCatalog<Catalog2> {
#Override
public Catalog2 getOld() { ... }
}
So far so good but the problem is that it becomes really cumbersome if I add some entities that must contain a link to a catalog of a certain type.
For instance,
abstract class AbstractCatalogHistory<C extends AbstractCatalog<C>, E extends AbstractHistoryEntry<C, E>> {
public abstract Set<E> getEntries();
}
abstract class AbstractHistoryEntry<C extends AbstractCatalog<C>, E AbstractHistoryEntry<C, E>> {
public abstract E getPrior();
}
class Cat1HistoryEntry extends AbstractHistoryEntry<Catalog1, Cat1HistoryEntry> {
#Override
public Cat1HistoryEntry getPrior() { ... }
}
class Cat2HistoryEntry extends AbstractHistoryEntry<Catalog2, Cat2HistoryEntry> {
#Override
public Cat2HistoryEntry getPrior() { ... }
}
class Catalog1History extends AbstractCatalogHistory<Catalog1, Cat1HistoryEntry> {
#Override
public Set<Cat1HistoryEntry> getEntries() { ... }
}
class Catalog2History extends AbstractCatalogHistory<Catalog2, Cat2HistoryEntry> {
#Override
public Set<Cat2HistoryEntry> getEntries() { ... }
}
so it gets much more difficult to get idea of what's going on while looking at such a hierarchy. This example is by no means complete and I have dozens of types that should be nested within those I provided above.
What I'm trying to do by doing this is to take advantage of type safe code which can be verified at compile time. But at the same time such a code becomes completely messy as I have to specify longer generics chains while adding new types to the hierarchy.
Is there a way to handle such generics explosion?
Your example doesn't make it entirely clear why you need to have separate classes for Catalog1 and Catalog2, but let's assume this is set.
However, even so I see no reason why everything else referencing these catalogs would require this kind of duplication. If you just want to make sure it's associated with the right catalog type, then this is the only generic parameter you should really need:
class CatalogHistory<C extends AbstractCatalog<C>> {
public Set<HistoryEntry<C>> getEntries();
}
class HistoryEntry<C extends AbstractCatalog<C>> {
public HistoryEntry<C> getPrior();
}
But what if you are actually doing different things in e.g. Cat1HistoryEntry and Cat2HistoryEntry so you need the separate classes? In that case you can obviously not get around having the abstract base class and two concrete implementations, but I see no need to introduce generic types and then nail them down to the concrete types the way you do:
abstract class AbstractHistoryEntry<C extends AbstractCatalog<C>> {
public abstract AbstractHistoryEntry<C> getPrior();
}
class Cat1HistoryEntry extends AbstractHistoryEntry<Catalog1> {
#Override
public Cat1HistoryEntry getPrior() { ... }
}
class Cat2HistoryEntry extends AbstractHistoryEntry<Catalog2> {
#Override
public Cat2HistoryEntry getPrior() { ... }
}
There are a few things going on here. First, consider AbstractHistoryEntry. If you have one of those, you are working on a generic level and should not care that getPrior returns this or that concrete subtype - all you need to know is that it returns another AbstractHistoryEntry object referencing the same catalog.
If you have a concrete Cat1HistoryEntry reference however, you can still get the full type safety of getting another Cat1HistoryEntry out of getPrior thanks to the covariance of return types in Java.
Now it gets slightly more complicated - Let's try to pull the same trick with AbstractCatalogHistory:
abstract class AbstractCatalogHistory<C extends AbstractCatalog<C>> {
public abstract Set<? extends AbstractHistoryEntry<C>> getEntries();
}
class Catalog1History extends AbstractCatalogHistory<Catalog1> {
#Override
public Set<Cat1HistoryEntry> getEntries() { ... }
}
class Catalog2History extends AbstractCatalogHistory<Catalog2> {
#Override
public Set<Cat2HistoryEntry> getEntries() { ... }
}
As you can see, both concrete subclasses still return a set of the concrete types Cat1HistoryEntry and Cat2HistoryEntry. The abstract base type now needs to express a common supertype for those sets so that you can work with the result in a generic way. This is done by introducing covariance.
Setters
Setters complicate the matter a bit. Basically, if you have a generic container / collection like a List<T> or an AbstractCatalogHistory<C>, and you want to allow both adding and retrieving items, you can no longer have variance in the item type if you want type safety.
For example, if you had a setter in AbstractCatalogHistory<C> which allows you to add any AbstractHistoryEntry<C> items to the history, then you have a problem, because if your AbstractCatalogHistory<C> is actually a Catalog1History then you only want Cat1HistoryEntry items in there!
This is the same problem as with generic lists: A List<Cat> is not a List<Mammal> because you can add an elephant to a List<Mammal>, but you shouldn't be able to add an elephant to a List<Cat>.
If you insist that a history for Catalog1 must consist only of Cat1HistoryEntry items, then a solution would be to only add a setter to Catalog1History, and none to AbstractCatalogHistory<C>. That way the generic classes would only be used for reading the history, not writing it.
However, going back to the beginning of my answer: If you don't actually don't need the dual concrete classes, the solution remains very simple. Unfortunately you still didn't explain why or if you need those. If all you really want is the Catalog1 / Catalog2 distinction, and you don't actually need a different implementation for e.g. Cat1HistoryEntry and Cat2HistoryEntry, then the following should suffice:
class CatalogHistory<C extends AbstractCatalog<C>> {
public Set<HistoryEntry<C>> getEntries();
public void addEntry(HistoryEntry<C> entry);
}
class HistoryEntry<C extends AbstractCatalog<C>> {
public HistoryEntry<C> getPrior();
public void setPrior(HistoryEntry<C> prior);
}

Best practices in achieving a great cohesion from multiple interfaces

First, sorry for imperfection in my wording, just let me know if there are unclear points.
While I am building the class structure of a java application, I wonder if there are the known best practices that I've not found yet in my case.
For example, There are A, B, C and more classes specifying device types, and each device has a tokenizer, parser, and compiler.
First, I have four interfaces like these.
interface Device {
public void x();
public int y();
public String z();
...
}
interface Tokenizer {...}
interface Parser {...}
interface Compiler {...}
And, the actual concrete classes are,
public class ADevice implements Device {...}
public class BDevice implements Device {...}
public class CDevice implements Device {...}
class ATokenizer implements Tokeninzer {...}
class BTokenizer implements Tokeninzer {...}
class CTokenizer implements Tokeninzer {...}
class AParser implements Parser {...}
...
class ACompiler implements Compiler {...}
...
Additionally and importantly, the "Device" classes and its interface are public so that will be contained in a stub lib. Anything else will only be included in the actual library and not visible to users who generate scripts by referring to the API.
Here is my question, (Long introduction :[ )
How to achieve the cohesion between each type and its corresponding interfaces.
In more detail, is there a way to determine whether they are paired right, between each type of device interface and its corresponding tokenizer, parser, or compiler interface in a compile time?
For example, there is a manager class that uses "Device" objects and "Tokenizer", "Parser", and "Compiler" objects. As you can see, "ADevice" objects can only be a pair with "ATokenizer", "AParser", or "ACompiler". However, if we define their type of the device objects from the interface, then there is no way we can tell if those objects are corresponding to the right "Tokenizer", "Parser", or "Compiler" object, except that "instanceOf" operator in a run time.
For instance, "ADevice" can be matched with "BTokenizer", "CParser", and so forth, and that will not generate the compile error.
I hope that I would like to hear a good answer or redirect to references.
One solution would be to paramaterize your interfaces:
interface Tokenizer<D extends Device> { ... }
interface Parser<D extends Device> { ... }
interface Compiler<D extends Device> { ... }
Then your implementations would be:
class ATokenizer implements Tokeniser<ADevice> { ... }
class BTokenizer implements Tokenizer<BDevice> { ... }
class CTokenizer implements Tokenizer<CDevice> { ... }
class AParser implements Parser<ADevice> { ... }
.
.
.
class ACompiler implements Compiler<ADevice> { ... }
You could then have a method in your Manager class that restrict them to the same type:
public <D extends Device> void doStuff(Tokeizer<D> tokenizer, Parser<D> parser, Compiler<D> compiler) { ... }
The compiler would then only allow it to be used as you descibe:
doStuff(new ATokeizer(), new AParser(), new ACompiler()); // works
doStuff(new ATokeizer(), new AParser(), new BCompiler()); // compiler error
Have you thought about generic interfaces?
With interface like below:
public interface Parser<E extends Device> {
void parse(E device);
void parse(String someString);
}
You could create class like this:
public class AParser implements Parser<ADevice> {
#Override
public void parse(ADevice device) {
//parse...
}
#Override
void parse(String someString) {
//parse...
}
}

Is there a way to guarantee an interface extends a class in Java?

Suppose I have the following situation:
public abstract class Vehicle {
public void turnOn() { ... }
}
public interface Flier {
public void fly();
}
Is there a way that I can guarantee that any class that implements Flier must also extend Vehicle? I don't want to make Flier an abstract class because I want to be able to mix a few other interfaces in a similar manner.
For instance:
// I also want to guarantee any class that implements Car must also implement Vehicle
public interface Car {
public void honk();
}
// I want the compiler to either give me an error saying
// MySpecialMachine must extend Vehicle, or implicitly make
// it a subclass of Vehicle. Either way, I want it to be
// impossible to implement Car or Flier without also being
// a subclass of Vehicle.
public class MySpecialMachine implements Car, Flier {
public void honk() { ... }
public void fly() { ... }
}
Java interfaces cannot extend classes, which makes sense since classes contain implementation details that cannot be specified within an interface..
The proper way to deal with this problem is to separate interface from implementation completely by turning Vehicle into an interface as well. The Car e.t.c. can extend the Vehicle interface to force the programmer to implement the corresponding methods. If you want to share code among all Vehicle instances, then you can use a (possibly abstract) class as a parent for any classes that need to implement that interface.
You could rearrange your classes and interfaces like this:
public interface IVehicle {
public void turnOn();
}
public abstract class Vehicle implements IVehicle {
public void turnOn() { ... }
}
public interface Flier extends IVehicle {
public void fly();
}
This way all implementations of Flier are guaranteed to implement the protocol of a vehicle, namely IVehicle.
If you have control on the Vehicle classes just extract Vehicle as an interface and then provide a base implementation.
If you have no control over Vehicle class, for example because it is part of a framework you are using or a third party library, it's not possible to do in Java.
The closest thing you can do is using Generics multiple wildcards notation.
<T extends Vehicle & Car>
But you can't really apply it directly to Car unless you do something like this:
public interface Car<T extends Vehicle & Car>() {
T self();
}
Which is bot weird and do not enforce the self method to actually return self, it's just a strong hint/suggestion.
You would implement a Car like this:
public class CitroenC3 extends Vehicle implements Car<CitroenC3> {
#Override
public CitroenC3 self() {
return this;
}
}
one can use a Car<?> like this:
Car<?> car = obtainCarInSomeWay();
Vehicle v = car.self();
Car c = car.self();
they should be both valid syntax.
What the compiler enforce here is that what you specify in Car<WHICH> as WHICH must both extend Vehicle and implement Car. And by adding self() you are saying to the programmer that the T object is supposed to be the object itself, thus forcing the wildcard instance to match the class if he want to be compliant with the specification.
in Java 8 you can even define a default implementation for the self method.
I also wish there was a better way to handle something like this.
It's a strange requirement, but you can accomplish something of the sort with Generics:
<T extends MyInterface & MyAbstractClass>
This question shows that you haven't grasped the essence of interface and class. Forgetting the concrete Java syntax right now, all you need to understand first is that: interface is a set of protocol, which should be implementation-agnostic. It makes no sense to let an interface extend a class(which is implementation-oriented).
Back to your concrete question, if you want to guarantee that a Flier is always a kind of Vehicle, just change the latter to an interface and let former extends it(It does make sense to extend one protocol from the other protocol). After that, you may create any class(abstract or concrete) that implements Vehicle or Flier.
Define a new Package
Create a new interface (ie. HiddenOne) with scope "default" with a method "implementMe(HiddenOne)"
Move Vehicle and Flier to the new Package.
Inherit Vehicle and Flier from HiddenOne
Implement the method implementMe in Vehicle.
Now: Whenever you like to implement from "Flier" you must extends from Vehicle !
(because only Vehicle can implement implementMe).
This is tricky but works great.

Can an interface demand that a class define an internal enum?

I want to define an interface, so that all the classes implementing it will define an internal enum named Fields. Is that possible in Java?
EDIT: I am creating a dynamic web application using Java (Servlets/JSP). I am trying to get my models to all have save() methods, so that they will be stored in the database. To represent the data and the fields of, say, a user in the system, I want to use Map<User.Fields, Object>. But I want to put the save() method in an interface, so I want to make sure that all the saveable objects have a Fields enum. For example, the User class can define something like:
public class User {
enum Fields { USERNAME, PASSWORD }
}
No you can't .
Why not have the enum in the parent interface.
EDIT to answer the EDIT of question:
You shouldn't do like this. Instead have a interface like this:
interface Saveable
{
Object[] getSaveFields();
}
Just look for the memento pattern, it may help you.
As Suraj said, nope, not possible. What is your intention by this however? If each subclass defines its own set of fields, You could force a getFields method, returning a Set of objects implementing another interface (and / or Enum). Or just going by names, are you needing the reflexions API (i.e. getClass().getDeclaredFields() )?
One technique I've used to address this issue is is to define an enum-typed interface, so you can "join" a particular enum with a class, then define that enum with the subclass, like this:
public interface MySuper<T extends Enum<T>> {
void someMethod(T someEnum);
}
public class MySubClass implements MySuper<MyEnum> {
public static enum MyEnum {
ONE, TWO, THREE
}
void someMethod(MyEnum myEnum) {
// do something
}
}
Oddly, you have to import static mypackage.MySubClass.MyEnum;
no, but you can do something like:
enum E {
e1,e2
}
interface I{
Enum getEnum();
}
interface I2 {
EnumSet getEnums();
}
class I2Impl implements I2 {
#Override public EnumSet getEnums() {
return EnumSet.allOf(E.class);
}
}
public class Main {
public static void main(String[] args) {
System.out.println(new IImpl().getEnum());
System.out.println(new I2Impl().getEnums());
}
}

generic interface: list of something specific

I want to define an interface MyList which is a list of interface MyThing. Part of the semantics of MyList is that its operations don't have any meaning on objects which do not implement the MyThing interface.
Is this the right declaration?
interface MyList<E extends MyThing> extends List<E> { ... }
edit: (part 2) Now I have another interface that returns a MyList as one of its methods.
// I'm defining this interface
// it looks like it needs a wildcard or template parameter
interface MyPlace {
MyList getThings();
}
// A sample implementation of this interface
class SpecificPlace<E extends MyThing> implements MyPlace {
MyList<E> getThings();
}
// maybe someone else wants to do the following
// it's a class that is specific to a MyNeatThing which is
// a subclass of MyThing
class SuperNeatoPlace<E extends MyNeatThing> implements MyPlace {
MyList<E> getThings();
// problem?
// this E makes the getThings() signature different, doesn't it?
}
Yes, at least that is how EnumSet does it.
public abstract class EnumSet<E extends Enum<E>>
extends AbstractSet<E>
Edit in answer to Part 2:
I'm not sure why the return type of getThings() in the interface doesn't complain about raw types. I suspect that because of type erasure, warnings in interfaces would be useless even if they were there (there's no warning if you change the return type to List, either).
For the second question, since MyNeatThing extends MyThing, E is within its bounds. That's sort of the point of using the extends bound in the generic parameter, isn't it?
For part 1, yes that looks right.
For your part 2, I suggest something like the following. The method returns a MyList of something, which you don't know what it is (it is different for different implementations apparently), but you know it's a subtype of MyThing.
interface MyPlace {
MyList<? extends MyThing> getThings();
}
Keep in mind that implementing interfaces like java.util.List correctly is hard; so ask yourself all of these questions:
Can I use java.util.List "as is", do
I need to add/remove functionality?
Is there something simpler I could implement, like Iterable<T>?
Can I use composition? (vs. inheritance)
Can I find the
newly desired functionality in
existing libraries like Google
Collections?
If I need to
add/remove functionality, is it worth
the added complexity?
That said, you could probably just use java.util.List for your example:
interface MyPlace<T extends MyThing> {
List<T> getThings();
}
class SpecificPlace implements MyPlace<MyThing> {
public List<MyThing> getThings() { return null; }
}
class SuperNeatoPlace implements MyPlace<MyNeatThing> {
public List<MyNeatThing> getThings() { return null; }
}

Categories