我可以重载 Java 中的接口方法吗?

Can I overload an interface method in Java?

我有一个数据描述接口:

public interface DataDescription {
     int getId();
}

还有两个实现:

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

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

现在我有了这个界面:

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

我想用一个 class 来实现 DataProcessor,像这样:

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)
    }
}

还有一些调用它的代码:

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

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

我想实现的是 DataProcessor 调用者不必担心数据转换(他们有一个 DataDescription 并且不必知道这两种类型).另外我想避免 instanceof 代码。

我所做的假设是我可以像这样重载接口方法。我在查看 section 15.12 of the java language specification 时无法找到这方面的证据(这并不意味着它不存在...)。

我关于重载的假设是否正确?我可以避免 instanceof 吗?

您可以使用抽象 class 为您处理转换,或者在接口中使用 Java8 的默认方法。

只需将关键字 'default' 添加到您界面中的方法中,并为其提供主体。

不,这行不通。

您的代码中没有重载。 dataProcessor的静态类型是DataProcessor,而DataProcessor只有一个process方法。

如果您将 dataProcessor 的静态类型更改为 DataProcessorImpl,您仍然不会获得所需的结果,因为重载分辨率是在编译时确定的。因此,由于 data 的编译时类型是 DataDescriptiondataProcessor.process(data) 仍将调用 public void process(DataDescription data) 而不是 public void process(DataWithId1 data).

DataDescription接口的方法中加入"something specific"就很简单了。

process() 方法属于每个子类型。你放错界面了。

DataProcessor 在每个 DataProcessor:

上调用该方法
public interface DataDescription {
     void somethingSpecific();
}

多态性起作用:

public class DataProcessorImpl implements DataProcessor {
    @Override
    public void process(DataDescription data) {
        data.somethingSpecific();  // polymorphism does it for you here
    }
}

也许您正在寻找 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);
    }
}