If I have a bunch of classes that all contain an Enum and EnumMap and I want to create a superclass for those classes.
public interface ColorEnum {
}
class ColorMarbles extends Toy {
enum MARBLE implements ColorEnum
{ BLUE, GREEN }
EnumMap<MARBLE, String> names = new EnumMap<MARBLE, String>(MARBLE.class);
//stuff
// fields
public void populate(ArrayList<String> designer) {
int i = 0;
for(MARBLE marble : MARBLE.values()) {
marble.name = designer.get(i);
i++;
}
}
}
class ColorBalloons extends Toy {
enum BALLOON implements ColorEnum
{ YELLOW, RED }
EnumMap<BALLOON, String> names = new EnumMap<BALLOON, String>(BALLOON.class);
//stuff
// fields
public void populate(ArrayList<String> designer) {
int i = 0;
for(BALLOON balloon : BALLOON.values()) {
balloon.name = designer.get(i);
i++;
}
}
}
How do I make create a superclass to have a generic EnumMap that contains an enum of type ColorEnum like this?
public abstract class Toy {
EnumMap<ColorEnum, String> names;
}
eidt: I realize that I was too vague with my example. Dogs are probably a bad example. I change it to something hopefully more clear.
What I have is a bunch of classes with methods like populate which populates the EnumMap. The names are in a predefined order. Instead of defining populate in every class, I'm hoping to be able to bring it to the Toy superclass so I don't have to keep copy-pasting in each new class type Toy.
Hopefully this will explain more what I'm looking for.
I have a feeling your design is needlessly overcomplicated.
With enums
If you don't require a class inheritance, you can work with enums directly as with top level classes.
public interface Animal {}
public enum Dog implements Animal {
HUSKY("Husky"), LAB("Labrador");
private final String name;
Dog(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Enums can declare fields, methods and implement interfaces like any other Java classes. Their only limitation is that their direct superclass is always java.lang.Enum
and they can't be extended.
However every enum constant can have its own set of unique data passed to its constructor. It is even possible that each of the constants can override a common method of that enum with its unique implementation.
A nice tutorial explaining more about the full power of enums: http://javarevisited.blogspot.cz/2011/08/enum-in-java-example-tutorial.html
Without enums
In case you need an actual class inheritance for sharing some common methods (for example from the Animal
superclass), I still would drop the map approach and rather try something more OOP oriented:
public class Animal {
}
public abstract class Dog extends Animal {
public abstract String getName();
public static class Husky extends Dog {
@Override
public String getName() {
return "husky";
}
}
public static class Lab extends Dog {
@Override
public String getName() {
return "labrador";
}
}
}
One mechanism I have used for something like this is to extend a generic base class that has a generic parameter that allows you to pass the Enum
details up to it.
This example defines a base Table
class for database tables:
public class Table<Column extends Enum<? extends Column>> {
// Name of the table.
protected final String tableName;
// All of the columns in the table. This is actually an EnumSet so very efficient.
protected final Set<Column> columns;
/**
* The base interface for all Column enums.
*/
public interface Columns {
// What type does it have in the database?
public Type getType();
}
// Small list of database types.
public enum Type {
String, Number, Date;
}
public Table(String tableName,
Set<Column> columns) {
this.tableName = tableName;
this.columns = columns;
}
}
Now you can subclass this:
public class VersionTable extends Table<VersionTable.Column> {
public enum Column implements Table.Columns {
Version(Table.Type.String),
ReleaseDate(Table.Type.Date);
// Sadly all of this must be in ALL of your enums but most of the work can be pushed up to `Table`
final Table.Type type;
Column(Table.Type type) {
this.type = type;
}
@Override
public Type getType() {
return type;
}
}
public VersionTable() {
super("Versions", EnumSet.allOf(Column.class));
}
}
and make use of functionality in the parent class that handles your enum.
Note here I am passing an EnumSet
to the Table
constructor. I am sure you could change this to accommodate your EnumMap
requirement if you decide an EnumSet
is insufficient.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With