Bryan Schmiedeler
Bryan Schmiedeler

Reputation: 3137

How to structure 3 classes with only one difference

I have 3 classes I need to write in Java. They are called Task1, Task2, and Task3, for arguments sake.

The three tasks are exactly the same except that they are different "types" of tasks. So the field type for Task1 will be "Task1" and so on.

Originally I wrote three classes with this one difference. But I think it would be better to write a base class Task and just extend this class in three subclasses [I am obviously somewhat new to Java].

However, I cannot figure out how to do this.

My base call looks like this:

package com.scoular.model;

public class TaskBase implements Serializable {

    private static final long serialVersionUID = -5867831497684227875L;

    private String unid;
    private String type;
    private Number order;

    public TaskBase() {
    }

    public void create() {
        try {
            clear();
            newNote = true;
            Session session = Factory.getSession();
            Date date = new Date();
            crtDte = session.createDateTime(date);
            crtUsr = session.getEffectiveUserName();
        } catch (Exception e) {
            XspOpenLogUtil.logError(e);
        }
    }

    public void loadByUnid(String unid) {
...
    }

    public void loadValues(Document doc) {
...
    }

    private void clear() {
...
    }

    public boolean save() {

        boolean tmpSave = true;

            Document doc = null;
            Session session = Factory.getSession();
            Database PCDataDB = session.getDatabase(PCConfig.getpcDataDBpath());

            if (newNote) {
                doc = PCDataDB.createDocument();
                doc.put("order", this.getNextOrder(doc));
            } else {
                doc = PCDataDB.getDocumentByUNID(unid);
            }
            doc.put("title", title);
            doc.put("notes", notes);

            doc.save();

        return tmpSave;
    }

    // Getters and Setters for common fields

    public String getUnid() {
        return unid;
    }

    public void setUnid(String unid) {
        this.unid = unid;
    }

    public String getType(String type) {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public Number getOrder() {
        return order;
    }

    public void setOrder(Number order) {
        this.order = order;
    }

}

And my super class looks like this:

package com.scoular.model;

import com.scoular.model.TaskBase;

public class Task extends TaskBase implements Serializable {

    private static final long serialVersionUID = -5867831497684227875L;

    // Custom Fields

    public Task() {

        super();
        this.setType("Build");
    }

}

I have cut out some of the extraneous code. In essence I suppose I want an abstract class as I will never instantiate a TaskBase. I understand I could also do this with an implementation but I do not understand that very well.

Any help would be much appreciated.

Upvotes: 2

Views: 103

Answers (4)

Andonaeus
Andonaeus

Reputation: 872

Define an abstract class which describes the members and methods of your Task.

public abstract class Task{

    private String unid;
    private String type;
    private Number order;

    public Task() {

    }

    //if these are all the same for any subclasses, define them here instead of making them abstract
    public abstract void create();
    public abstract void loadByUnid(String unid);
    public abstract void loadValues(Document doc);
    protected abstract void clear();

    public String getUnid() {
        return unid;
    }

    public void setUnid(String unid) {
        this.unid = unid;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public Number getOrder() {
        return order;
    }

    public void setOrder(Number order) {
        this.order = order;
    }   
}

Since your concrete Tasks all perform different things, you can define concrete classes from your abstract Task which implement their own behaviors:

public class Task1Impl extends Task implements Serializable {

    private static final long serialVersionUID = -5867831497684227875L;

    // Custom Fields

    public Task1Impl() {

        super();
        this.setType("Build");
    }

    @Override
    public void create() {
        // TODO Auto-generated method stub

    }

    @Override
    public void loadByUnid(String unid) {
        // TODO Auto-generated method stub

    }

    @Override
    public void loadValues(Document doc) {
        // TODO Auto-generated method stub

    }

    @Override
    protected void clear() {
        // TODO Auto-generated method stub

    }

}

Upvotes: 0

Stepan
Stepan

Reputation: 1431

Java allows inheritance from only on e superclass. The "implement Interface" is a very powerful tool that you should learn. Please watch Derek Banas Java tutorials 15 and 16 (each less than 10 minutes) and try to use implementation. Ask for more help if these tutorials don't answer the question.

Upvotes: 0

Cory Klein
Cory Klein

Reputation: 55760

Java Generics May be helpful in this case.

class Task<T> {
    private T t;
    T getTask() { return t; }
    void setTask(T _t) { this.t = _t; }
}

Task<Task1> task1 = new Task<Task1>();
task1.setTask(sometask);

Upvotes: 1

rdonuk
rdonuk

Reputation: 3956

protected fields can be reached from the child classes. So you can make type field `protected and assign desired values in child classes.

TaskBase class:

`public abstract class TaskBase implements Serializable {

    private static final long serialVersionUID = -5867831497684227875L;

    private String unid;
    protected String type;
    private Number order;

Task class:

public class Task extends TaskBase implements Serializable {

    private static final long serialVersionUID = -5867831497684227875L;

    // Custom Fields

    public Task() {

        super();
        type = "build";
    }

}

Upvotes: 1

Related Questions