buddy123
buddy123

Reputation: 6327

Virtual behavior with java's inheritance with Generic parent

I have a "Data manager" class, which contains a list of some sort of object type Then, when I started getting my code advanced, I had the need for a different kind of manager, which has some similarities - loadData(..), saveData(..), add(..), remove(..) but also some differences, which is unique to each kind of manager, depending on the type of which it is "managing". So I decided to do the following structure: Generic class with singelton implementation for each child (At first, my manager was static as it has no sense of being multiple instances):

public abstract class GenericDataManager<T> {
    protected List<T> list;
    protected void saveData(Context context, String filePath) {..}
    protected void loadData(Context context, String filePath) {..}
..
}

and my two managers are the following:

public class ManagerA extends GenericDataManager<A> {
private static ManagerA instance = null;

    protected ManagerA() { }
    public static ManagerA getInstance() {
        if (instance == null)
            instance = new ManagerA();
        return instance;
    }

     private void saveData(Context context) {
        saveData(context, "fileA");
    }

    private void loadData(Context context) {
        loadData(context, "fileA");
    }
}

public class ManagerB extends GenericDataManager<B> {
private static ManagerB instance = null;

    protected ManagerB() { }
    public static ManagerB getInstance() {
        if (instance == null)
            instance = new ManagerB();
        return instance;
    }

     private void saveData(Context context) {
        saveData(context, "fileB");
    }

    private void loadData(Context context) {
        loadData(context, "fileB");
    }
}

I showed here only the similar pieces of code for the two managers, and you can already see the problem - Although I managed to make my similar piece of code implemented only one and reused for every specific implementation using generics and inheritance mechanism, I still need the only specific information, which is the data file to use.

Is there a way of the generic parent to request that information from its child, so that I wont need the redundant implementation in the child class?

Leaving it this way makes me feel Im missing something.

Upvotes: 0

Views: 42

Answers (3)

blgt
blgt

Reputation: 8205

Yes. Make an abstract getter in the parent class, and add implementation in children:

abstract class GenericDataManager<T> {

    protected void saveData(Context context) {
        String filePath = getFilePath();
    }
    protected void loadData(Context context) {
        String filePath = getFilePath();
    }
    protected abstract String getFilePath();
}

public class ManagerA extends GenericDataManager<A> {
    @Override protected String getFilePath() {
        return "fileA";
    }
}

Upvotes: 0

T.J. Crowder
T.J. Crowder

Reputation: 1075427

You could have the parent call back to the children, but it's generally poor practice. Inheritance always requires tightly coupling the children to the parent, but you generally want to avoid coupling the parent to the children.

Instead, perhaps in GenericDataManager:

protected void saveData(Context context, string fileName) {
    // do the generic work with the specific given file
}

protected void loadData(Context context) {
    // do the generic work with the specific given file
}

...and then in the subclasses:

private void loadData(Context context) {
    super.loadData(context, "loadA"); // or of course, "loadB"
}

Upvotes: 1

mikea
mikea

Reputation: 6667

How about:

public abstract class GenericDataManager<T> {
    protected abstract String getFilePath();
    protected List<T> list;
    protected void saveData(Context context) {
        String filePath = getFilePath();
        ..
    }
    protected void loadData(Context context) {
        String filePath = getFilePath();
        ..
    }
    ..
}

and then:

public class ManagerA extends GenericDataManager<A> {
    private static ManagerA instance = null;

    protected ManagerA() { }
    public static ManagerA getInstance() {
        if (instance == null)
            instance = new ManagerA();
        return instance;
    }

    protected String getFilePath() { return "fileA" );
}

public class ManagerB extends GenericDataManager<A> {
    private static ManagerB instance = null;

    protected ManagerB() { }
    public static ManagerB getInstance() {
        if (instance == null)
            instance = new ManagerB();
        return instance;
    }

    protected String getFilePath() { return "fileB" );
}

Upvotes: 2

Related Questions