Timo Timo - 4 months ago 8
Java Question

Can I overload an interface method in Java?

I have a data description interface:

public interface DataDescription {
int getId();
}


And two implementations:

public class DataWithId1 implements DataDescription {
// ... simple getter impl.
}

public class OtherDataWithId implements DataDescription {
// ... simple getter impl.
}


Now I have this interface:

public interface DataProcessor {
void process(DataDescription data);
}


I would like to implement the
DataProcessor
with one class, something like this:

public class DataProcessorImpl implements DataProcessor {
@Override
public void process(DataDescription data) {
// Do something...
}

public void process(DataWithId1 data) {
// Do something specific with this type (e.g. directly store in table of database)
}

public void process(OtherDataWithId data) {
// Do something specific with this type (convert to format DataWithId1 and then store in DB)
}
}


And some code to call it:

public Main {
private DataProcessor dataProcessor = new DataProcessor();

public static void main(String[] args) {
DataDescription data = new DataWithId1(1);
dataProcessor.process(data);
}
}


What I would like to achieve is that the
DataProcessor
caller doesn't have to worry about the data conversion (they have a
DataDescription
and don't have to know about the two types). Additionally I would like to avoid
instanceof
code.

The assumption I've made is that I can overload an interface method like this. I was unable to find proof for this when looking at section 15.12 of the java language specification (which doesn't mean it isn't there...).

Is my assumption about overloading correct? Can I avoid
instanceof
?

Answer

Maybe you are looking for the Visitor Pattern:

public interface DataDescription {
    int getId();
    void accept(DataProcessorImpl p);
}

public class DataWithId1 implements DataDescription {
    private final int id;

    public DataWithId1(int id) {
        this.id=id;
    }
    @Override
    public void accept(DataProcessorImpl p) {
        p.process(this);
    }
    @Override
    public int getId() {
        return id;
    }
    // ... simple getter impl.
}

public class OtherDataWithId implements DataDescription {
    private final int id;

    public OtherDataWithId(int id) {
        this.id=id;
    }
    @Override
    public void accept(DataProcessorImpl p) {
        p.process(this);
    }
    @Override
    public int getId() {
        return 42;
    }
    // ... simple getter impl.
}
public interface DataProcessor {
    void process(DataDescription data);
}

public class DataProcessorImpl implements DataProcessor {
    @Override
    public void process(DataDescription data) {
        data.accept(this);
    }

    public void process(DataWithId1 data) {
        System.out.println("process(DataWithId1)");
        // Do something specific with this type
        // (e.g. directly store in table of database)
    }

    public void process(OtherDataWithId data) {
        System.out.println("process(OtherDataWithId)");
        // Do something specific with this type
        // (convert to format DataWithId1 and then store in DB)
    }
}

public class Main {
    private static DataProcessor dataProcessor=new DataProcessorImpl();

    public static void main(String[] args) {
        DataDescription data = new DataWithId1(1);
        dataProcessor.process(data);
        data = new OtherDataWithId(100);
        dataProcessor.process(data);
    }
}