Search code examples
javaenumspolymorphismabstract-classsubclass

Java Object with subclasses of different type including enum


I like to think top/down rather than bottom/up, so here is directly my final goal :

My goal : A "aQuery" built with different "PlQryElement"s (Pl stands for 'Playlist' since the context here is a 'smart playlist' for music playlist manager) :

List<PlQry_Element> aQuery = new ArrayList<PlQry_Element>();

I should obviously instantiate the 'PlQry_Elements', and then use the aQuery.add(...);. Resulting of building up my final query.

Here is the "PlQry_Element" possible :

  • A "PlQryEl_Parentese" (open or close, parenthese) --> I used 'enum' for this
  • A "PlQryEl_Condition" (a condition having it's own building up) --> I used a specific object for this
  • A "PlQryEl_BoolOperator" (essentially 'AND' / 'OR') --> I used 'enum' for this

What I would think :

  • Using an abstract class : All "PlQryEl_..." should be subclasses from an abstract class "PlQryElement". But this obviously does not work with 'enum' which are not "implementable".
  • Another thought was to use Polymorphism... Could not get it to work.

Question : How can I achieve my very first goal... Without changing my 'enum' objects into 'classes' ?

Any help would be greatly appreciated !!! Thank you in advance ;-)...


Here are the classes WITHOUT 'implements' :

PlQryEl_Parenthese -->

package application.query.element;

public enum PlQryEl_Parenthese {
    PARENTHESES_OPEN("("),
    PARENTHESES_CLOSE(")");

    String symbol;
    
    PlQryEl_Parenthese(String symbol) {
        this.symbol = symbol;
    }
};

PlQryEl_Condition -->

package application.query.element;

import application.query.element.cond.PlQryEl_Cond_Object;
import application.query.element.cond.PlQryEl_Cond_Operator;

public class PlQryEl_Condition {
    PlQryEl_Cond_Object aObject = PlQryEl_Cond_Object.PLAYLIST;
    String sField="";
    PlQryEl_Cond_Operator aOparator = PlQryEl_Cond_Operator.EQUAL;
    String sValue = "";
    
    public PlQryEl_Condition(PlQryEl_Cond_Object aObject, String sField, PlQryEl_Cond_Operator aOparator, String sValue) {
        super();
        this.aObject = aObject;
        this.sField = sField;
        this.aOparator = aOparator;
        this.sValue = sValue;
    }
};

PlQryEl_BoolOperator -->

    package application.query.element;
    
    public enum PlQryEl_BoolOperator {
        LINK_OR("or"),
        LINK_AND("and");
    
        String symbol;
        
        PlQryEl_BoolOperator(String symbol) {
            this.symbol = symbol;
        }
    };

And for interest here are the objects about the 'PlQryEl_Condition' class :

PlQryEl_Cond_Object -->

package application.query.element.cond;

public enum PlQryEl_Cond_Object {
    PLAYLIST("Playlist","vPlaylist"),
    TRACK("Track","vTrack");

    String symbol;
    String dbViewName;
    
    PlQryEl_Cond_Object(String symbol, String dbViewName) {
        this.symbol = symbol;
        this.dbViewName = dbViewName;
    }
};

PlQryEl_Cond_Operator -->

package application.query.element.cond;

public enum PlQryEl_Cond_Operator {
    EQUAL("="),
    GREATER(">"),
    SMALLER("<"),
    EMPTY("is empty (null, NA, ...)"),
    INLIST("in list");

    String symbol;
    String dbViewName;
    
    PlQryEl_Cond_Operator(String symbol) {
        this.symbol = symbol;
    }
};

Solution

  • As more often than never the answer is inside the question... This was the case here !

    The solution I put in place was to wrap a 'class' around the enums in order to make them 'implementable'.

    This solved, obviously the case... But is it the only/best solution ?