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

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());
}
}

Related

Java subclass implementation mandatory constructor

Is there any way in Java to enforce a subclass or interface implementation to have a constructor with a given signature?
Let's say that I´ve got either:
public interface MyInterface {
// any methods
}
or
public abstract class MyBaseClass {
// any abstract methods
}
Now, is it possible to do anything to require
public class MySubClass extends MyBaseClass {
public MySubClass(String s) { }
}
or
public class MySubClass implements MyInterface {
public MySubClass(String s) { }
}
to always have a constructor that takes a String as it´s only input parameter?
The obvious workaround is to create a factory interface with a method taking a String and inject it where required. Which is not what I would like to do.
Not really, the closest I think you can get is something like:
abstract class B {
public B(String s) {
}
}
public class A extends B {
public A(String s) {
super(s);
}
}
This forces A to implement a non default constructor which must call super(String) but can not prevent the following:
public class A extends B {
public A() {
super("");
}
}
There have been many times where I wished something like this existed, but sadly it doesn't. Even something like what David Soroko suggested wouldn't work because a subclass still wouldn't be forced to have a String constructor - it can just pass any String it likes to super. Simply put, there is no such thing within the Java syntax itself.
I suppose the closest one could get to such a capability is if someone built an annotation processor that allows you to use an annotation like #MustHaveUnaryConstructor(String.class) and then if any subclass does not have such a constructor, it causes compilation to fail and tells you which subclass broke the contract. But I haven't found such a thing and I don't know enough about annotation processing to build one myself. So TL;DR, no, you can't.

Access the same method among different classes?

I am programming a simple platformer game, and I have several types of platforms. I created a class for the most simple type and made the rest subclasses, with the only difference between each class being the value of their variables (so they all share the same variable and method names).
In my collision detection, I loop through a HashMap. Within that HashMap are ArrayLists of the instances of each class. But when I use a nested loop to loop through try to call their methods implicitly, I have found that I cannot access these methods without explicitly declaring which class I want to call the method from.
I have done research, although the only way I can see of doing this is to loop through the instances of each class separately, meaning one loop per class; I would rather not do this, since it would be a lot more code than I feel is necessary.
In order to be able to call a common method on classes of different types you need to give your objects a common supertype declaring the common method - i.e. they should have a common superclass, or implement a common interface.
Interfaces provide an easier way of declaring common functionality, because a class can implement multiple interfaces, but it can extend only one class.
Provide an interface with the common method, then declare the map to use objects of that interface, i.e.
interface CommonInterface {
void commonMethod(int arg);
}
class One implements CommonInterface {
public void commonMethod(int arg) {
...
}
}
class Two implements CommonInterface {
public void commonMethod(int arg) {
...
}
}
Here is what you can do now:
Map<String,CommonInterface> myMap = new HashMap<>();
myMap.put("one", new One());
myMap.put("two", new Two());
for (Map.Entry<String,CommonInterface> e : myMap.entrySet()) {
System.out.println(e.getKey());
CommonInterface c = e.getValue();
c.commonMethod(123);
}
Simple, make each platform class implement an IPlatform interface or extand a base class. Look up java polymorphism and interfaces.
Are your subclasses overriding the common methods from the super class?
In other words, are your subclass' common methods declared in your simpler class?
If it is the case, you can simply call the method as if it is a simple class:
public abstract class Fruit {
public abstract void method();
}
public class Apple extends Fruit {
#Override
public void method() {
System.out.println("I'm an apple");
}
}
public class Orange extends Fruit {
#Override
public void method()
System.out.println("I'm an orange");
}
}
Using this you can simply call your method from any fruit, since it has your method declared. No need to know which fruit it is. The following code:
Fruit fruit = new Orange();
fruit.method();
will output: "I'm an orange".

How to use generics with multiple coupled objects?

So I'm having trouble wrapping my head around the proper design for this.
My application has two key objects that control state, that need to interact with one another: ItemList, ItemState. These each rely on a generic ITEM_TYPE so they can function in different contexts. They are also abstract to allow for ITEM_TYPE-dependent behavior.
Both pieces need to know the generic type, but moreover, since they talk to one another, they need to know the generic types of one another. (An ItemList< String > instance needs to know that its ItemState field is an ItemState< String > and vice versa).
My current solution works, but it seems awful. There has to be a better way. This is what I'm doing now:
public abstract class ItemState<
ITEM_TYPE,
STATE_TYPE extends ItemState<ITEM_TYPE, STATE_TYPE, LIST_TYPE>,
LIST_TYPE extends ItemList<ITEM_TYPE, STATE_TYPE, LIST_TYPE>> {
}
public abstract class ItemList<
ITEM_TYPE,
STATE_TYPE extends ItemState<ITEM_TYPE, STATE_TYPE, LIST_TYPE>,
LIST_TYPE extends ItemList<ITEM_TYPE, STATE_TYPE, LIST_TYPE>> {
}
Then an implementing class might look like:
class StringState extends ItemState<String, StringState, StringList> {
}
class StringList extends ItemList<String, StringState, StringList> {
}
Note that for ItemState, STATE_TYPE is a reference back to the implementing class, and likewise for ItemList/LIST_TYPE.
Really my problem would be solved if I just make ItemState an inner class of ItemList since there would be an implicit binding and they could share generic declarations, but both classes are so large and standalone, that I would prefer not to do this.
Any suggestions?
Edit: As a counter-example to a comment:
public abstract class ItemState<ITEM_TYPE> {
public abstract ItemList getItemList();
public void doSomething() {
// This should not compile because abstract super class has
// no idea what the generic type of getItemList() is
ITEM_TYPE item = this.getItemList.getItem();
}
}
Edit 2: I think the best solution I could think of was just to make ItemList/ItemState inherit one way or the other so they can function as the same class. I don't love this solution because it overrides separation of concerns, but it makes the generics a lot more manageable.
Sidenote: my actual applicaiton had this problem with 4 intertwined classes, I just used 2 for simplicity. In actuality the generics were so bad they were incomprehensible and hard to refactor (about 4 entire lines of just generic declarations for each class). I've now made these 4 classes into a vertical inheritance hierarchy
JM Yang's solution is pretty good
I think you may just reference to generic type ITEM_TYPE when declaring these 2 classes.
I'm able to compile below code with no errors.
public abstract class ItemList<ITEM_TYPE> {
public abstract ItemState<ITEM_TYPE> getState();
public abstract ITEM_TYPE getItem();
}
public abstract class ItemState<ITEM_TYPE> {
public abstract ItemList<ITEM_TYPE> getItemList();
public void doSomething() {
ITEM_TYPE item = getItemList().getItem();
System.out.println(item);
}
}
public class StringList extends ItemList<String> {
#Override
public StringState getState() {
return new StringState();
}
#Override
public String getItem() {
return "";
}
}
public class StringState extends ItemState<String> {
#Override
public StringList getItemList() {
return new StringList();
}
}

What's the point in having an abstract class with no abstract methods?

Can have an abstract class implementing all of its methods-- with no abstract methods in it.
Eg.:
public abstract class someClass {
int a;
public someClass (int a) { this.a = a; }
public void m1 () { /* do something */ }
private void m2 () { /* do something else */ }
}
What's the advantage, if any, of having such an abstract class compared to having the same class as a concrete one instead?
One i can think of is that, when i declare it as abstract, it won't be instantiated.
however, i can have the same effect by making it concrete and its constructor(s) private.
TIA.
//==================
EDIT: One other use I can think of:
it may be extending another abstract class or implementing an interface without implementing that class's abstract methods-- although it is implementing all methods of its own. for whatever it' worth.
It has a conceptual meaning: this class has a behaviour which makes no sense on its own.
Granted, it's difficult to imagine such a scenario without well-defined extension points (i.e. abstract methods), but occasionally it will be a reasonably accurate model of your problem.
You can have something like this:
public abstract class ObjectWithId {
private final String id;
public ObjectWithId( String id ) {
this.id = id;
}
public final String getId() {
return id;
}
}
And then you can extend it to declare different types of objects that have ids. Here you have a fully specified and implemented behaviour but no restriction on any other behaviours subclasses may exhibit.
Note though that a much neater way to model the same thing is to use composition instead of inheritance.
public final class ObjectWithId<T> {
private final String id;
private final T ob;
public ObjectWithId( String id, T ob ) {
this.id = id;
this.ob = ob;
}
public String getId() {
return id;
}
public T getObject() {
return ob;
}
}
But before generics were introduced (up to Java version 1.4), this wouldn't have been as elegant and obviously better than the abstract class solution because you'd have had to trade in type safety.
you can declare to implement an interface and don't provide implementation and then each child implicitly gets interface extended
you prevent to create instance of this class
you in future provide common implementation to all children
As you pointed out, you can prevent the class from being instantiated by making it's constructor private. Othere than that, there is no benefit whatsoever. This is probably supported just to provide language completeness.
We generally use Abstraction concept with inheritance
Consider using abstract classes if any of these statements apply to
your situation:
You want to share code among several closely related classes.
To answer your question,
Why declare a class with concrete methods Abstract?
One possible reason is to support inheritance without actually creating objects
Assume you have two classes one Abstract and other Concrete
Abstract class : AbsClass
abstract class AbsClass {
int a = 5;
//Constructor
public AbsClass() {
System.out.println(a);
}
void methodA() {
System.out.println(a + 10);
}
}
and
Concrete class : ConcreteClass
class ConcreteClass {
int a = 10;
//Made the constructor Private to prevent from creating objects of this class
private ConcreteClass() {
System.out.println(a);
}
void methodA() {
System.out.println(a + 10);
}
}
The above two classes should function similarly (?) Until you try to Subclass them
class AbsImplementer extends AbsClass {
//Works fine
}
class ConcImplementer extends ConcreteClass {
//Compilation Error Implicit super constructor ConcreteClass() is not visible
}
The practical difference is that you can't create an instance of it. You would have to subclass it and create an instance of the subclass.
As to WHY you would want to do this, in practice ... I'm hard pressed to think of a good reason. You could say that the class is only meaningful if someone creates a subclass that implements some function. But then why not make that function abstract in the super-class?
I wouldn't rule out the possibility that someone might come up with some example where this makes sense, but I can't think of one. Just because it's possible to write a piece of code and that code compiles successfully doesn't mean that that it makes sense. I mean, I can write "total_price = item_price * zip_code + customer_height_in_cubits - 7.879", but that doesn't mean such a line of code would be meaningful.
Well assume that you don't care whether the methods of the abstract class are implemented or abstract, but by design it has to be abstract so that when someone extends it, they have to add more methods or override the existing ones or use as is. If they don't want to override the methods then the default behavior is already provided in that abstract class.
In this abstract class, the only criteria you enforce is - one simply cannot instantiate that class and they have to have their only version of class before using it.
So in general, abstract class with few or all methods being implemented, is much better than having an interface which has no methods implemented at all. This is based on the assumption that you are using it as a single inheritance.
Consider something similar to the NVI pattern (not sure what you'd call it in Java):
public abstract class A {
public final void doSomething() {
System.out.println("required");
doOptional();
}
protected void doOptional() {
System.out.println("optional");
}
}
public class B extends A {
#Override
protected void doOptional() {
System.out.println("overridden");
}
}
For your public API, you only expose a public final method which cannot be overridden. It performs some required work inside there and an optional method. When extending this class, you can only override doOptional().
Calling B.doSomething() will always print "required" before it proceeds.
Since doOptional() is not abstract, there's no purely code reason that class A needs to be abstract. But it might be desired for your particular project. For example, a base service that is always extended into specific sub-projects.
This can be useful for cases when the classes derived from the abstract base class must have some behaviour that is different from each other but that behaviour can not be abstracted as residing within a method that has the same signature for all the classes. Being unable to share a signature can occur if the different behaviour requires methods that are passed different primitive types. Because they use primitive types you can not use generics to express the similarity.
An abstract base class without any abstract methods is acting a bit like a marker interface, in that it is declaring that implementing classes must provide some behaviour without having that behaviour encapsulated within a new method with a signature that is the same for all implementations. You would use an abstract base class rather than a marker interface when the implementing classes have some behaviour in common, especially if the base class can implement it for the derived classes.
For example:
abstract class Sender {
protected final void beginMessage() {
...
}
protected final void endMessage() {
...
}
protected final void appendToMessage(int x) {
...
}
}
final class LongSender extends Sender {
public void send(int a, int b, int c) {
beginMessage();
appendToMessage(a);
appendToMessage(b);
appendToMessage(c);
endMessage();
}
}
final class ShortSender extends Sender {
public void send(int a) {
beginMessage();
appendToMessage(a);
endMessage();
}
}
It can be useful if you consider it an utility class.

A class implementing an interface that takes an enum

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.

Categories