我一直试图找到一种方法来做以下事情,但不确定它是否可能。假设我有一个超类和两个具有完全不同且独立的字段的子类(类Field1
和Field2
):
public abstract class Parent {
private String field;
// getters and setters
}
public class Child1 extends Parent {
private Field1 field1;
}
public class Child2 extends Parent {
private Field2 field2;
}
现在,我有一个接口,其接受Parent
类的方法,以及两个实现该接口的实现Impl1
和Impl2
,但我希望它们接受子类:
public interface IMethod {
void method(Parent parent);
}
public class Impl1 implements IMethod {
@Override
public void method(Child1 child1) { // like this won't compile
// implementation using Field1
}
}
public class Impl2 implements IMethod {
@Override
public void method(Child2 child2) { // like this won't compile
// implementation using Field2
}
}
我一直在尝试以不同的方式使用泛型来实现这一点,所以我避免从Parent
转换到方法实现中的子类。问题是我对仿制药还不是很熟悉,所以不确定这是否可行或者没有解决方案。
答案 0 :(得分:2)
您需要更改
public interface IMethod {
void method(Parent parent);
}
到
public interface IMethod<T extends Parent>{
void method(T parent);
}
以及您的实施
public class Impl1 implements IMethod<Child1> {
@Override
public void method(Child1 child1) {
// implementation using Field1
}
}
和
public class Impl2 implements IMethod<Child2> {
@Override
public void method(Child2 child2) {
// implementation using Field2
}
}
答案 1 :(得分:1)
这里有几个不同的解决方案,每个都有一些优点和缺点。 e.g:
好奇地反复出现模板模式:
interface IMethod<Child extends Parent> {
void method(Child child);
}
public class Impl1 implements IMethod<Child1> {
@Override
public void method(Child1 child1) {
// implementation using Field1
}
}
public class Impl2 implements IMethod<Child2> {
@Override
public void method(Child2 child2) {
// implementation using Field2
}
}
它易于实现和使用,但也不是很灵活 - 每个子类都严格地绑定到它接受作为参数的类。
方法重载:
interface IMethod {
void method(Parent parent);
}
public class Impl implements IMethod {
@Override
public void method(Parent parent) {
// generic implementation
}
public void method(Child1 child1) {
// implementation using Field1
}
public void method(Child2 child2) {
// implementation using Field2
}
}
这也可以让您轻松扩展功能 - 但它需要在编译时知道确切的传递类型。
double displatch - 在大多数OO语言中使用访问者模式实现:
class Parent {
private String field;
void visit() {
// generic implementation
}
}
public class Child1 extends Parent {
private Field1 field1;
@Override
void visit() {
// implementation using Field1
}
}
interface IMethod {
void method(Parent parent);
}
public class Impl implements IMethod {
@Override
public void method(Parent parent) {
parent.visit();
}
}
它适合您的示例,但需要一些样板。
如果您确定必须处理Parent
,我建议visitor
。但总的来说,你可以使用更简单的东西:
class Parent {
// fields
public void handle() {
// Parent's fields
}
}
class Child1 extends Parent {
// fields
@Override
public void handle() {
// Child's fields
}
}