2

I have multiple classes that implement method create.

public TeamScorePk create(TeamScore entity) {
    TeamScorePk pk = entity.getPk();
    if (!pk.validate()) {
        throw new IllegalArgumentException("Part of primary key is null:" + entity);
    }
    if (INSTANCES.containsKey(pk)) {
        throw new IllegalArgumentException(entity + " already exists.");
    }
    INSTANCES.put(pk, entity);
    return pk;
}

Map INSTANCES serves like DB table. The only difference between the create method in different classes are the types it uses. Thus I'd like to put the method into an abstract super class. Problem is with the map INSTANCES, because I have to get it from the extending classes. I could declare abstract method getInstances, but I have problem with the type of the Map it should return. If I use something like Map<? extends Pk, ? extends Entity>, I naturally get and error when putting types Pk and Entity into it.

Could someone give me an example or some advice, how the abstract class should look like?

1
  • 1
    If the things you put in there will all be Pk and entity, or extensions of those classes, try Map<Pk,Entity>. "ChildOfPk" still IsA "Pk" Commented Mar 10, 2014 at 19:45

2 Answers 2

1

I would make the abstract superclass generic with the types of keys and values that the subclasses would handle.

public abstract class SomeSuperclass<K extends Pk, V extends Entity> {

Then you can place the algorithm in a concrete method.

    public K create(V entity) {
        K pk = entity.getPk();
        if (!pk.validate()) {
            throw new IllegalArgumentException("Part of primary key is null:" + entity);
        }
        if (getInstances().containsKey(pk)) {
            throw new IllegalArgumentException(entity + " already exists.");
        }
        getInstances().put(pk, entity);
        return pk;
    }

    public abstract Map<K, V> getInstances();
}

I have replaced INSTANCES with getInstances(), an abstract method that subclasses will implement.

public class TeamScoreSubclass extends SomeSuperClass<TeamScorePk, TeamScore> {

Then all the subclass has to do is supply the Map (and populate it somehow).

   Map<TeamScorePk, TeamScore> map = new HashMap<>;

and

   public Map<TeamScorePk, TeamScore> getInstances() {
        return map;
   }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Now there is a problem in line K pk = entity.getPk();. Entity<K extends Pk> is an abstract class which declares one abstract method K getPk(). I would have to cast entity.getPk() to K for this to work. Where am I still doing something wrong?
1
public abstract class BaseClass<P extends Pk, E extends Entity> {

    protected abstract Map<P, E> getInstances();
}

public class ChildClass extends BaseClass<TeamScorePk, TeamScore> {

    protected Map<TeamScorePk, TeamScore> getInstances() {
        // ...
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.