我可以重载 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
的编译时类型是 DataDescription
,dataProcessor.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);
}
}
我有一个数据描述接口:
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
的编译时类型是 DataDescription
,dataProcessor.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);
}
}