假设我们有以下代码:
class Parent {}
class Child1 extends Parent {}
class Child2 extends Parent {}
class Main {
static void method(Parent obj) {}
static void method(Child1 obj) {}
static void method(Child2 obj) {}
public static void main(String[] arg) {
Parent obj1 = new Child1();
Parent obj2 = new Child2();
method(obj1); //call method(Child1 obj)
method(obj2); //call method(Child2 obj)
}
}
如何获得类似的效果,因此可以将对象传递给具体方法而不是一般方法?
------------------------服务器参数示例--------------
class Parent {}
class Child1 extends Parent {}
class Child2 extends Parent {}
class Main {
static void method(Parent obj1, Parent obj2) {}
static void method(Child1 obj1, Child1 obj2) {}
static void method(Child1 obj1, Child2 obj2) {}
public static void main(String[] arg) {
Parent obj1 = new Child1();
Parent obj2 = new Child2();
method(obj1, obj1); //call method(Child1 obj1, Child1 obj2)
method(obj1, obj2); //call method(Child1 obj1, Child2 obj2)
}
}
答案 0 :(得分:1)
您在问什么方法重载。方法重载是在编译时解决的,因此使用相关变量的编译时类型来确定要执行的方法。
因此,method(obj1
和method(obj2)
将始终调用static void method(Parent obj)
,因为obj1
和obj2
的编译时间类型为Parent
。 / p>
答案 1 :(得分:0)
我找到了这样的解决方案:
class Parent {}
class Child1 extends Parent {}
class Child2 extends Parent {}
public class Main {
static void method(Parent obj) {
System.out.println("Parent");
if(obj instanceof Child1)
{
method((Child1) obj);
return;
} else if(obj instanceof Child2)
{
method((Child2) obj);
return;
}
}
static void method(Child1 obj) {
System.out.println("Child1");
}
static void method(Child2 obj) {
System.out.println("Child2");
}
public static void main(String[] arg) {
Parent obj1 = new Child1();
Parent obj2 = new Child2();
method(obj1); //call method(Child1 obj)
}
}
对于此代码,输出为:
Parent
Child1
因此,这意味着当我们放置类型为Child1的对象时,将调用Parent方法,然后在此方法中检查对象是否为Child1类型,如果是,则为Child1调用方法。
除非作为参数传递给此方法的对象是Parent类型,否则无法调用Child1或Child2
答案 2 :(得分:0)
背景:编写编译器项目时,我遇到几乎相同的问题。
简短答案:如果您坚持使代码可扩展,并且易于编写(就像问题中的代码示例一样),那么大概必须添加反射(尽管它可能对静态分析仪不友好)。
示例:
import java.lang.reflect.*;
import java.util.*;
class Value {}
class IntValue extends Value {
private int value;
public int value() {
return value;
}
public IntValue(int value) {
this.value = value;
}
public String toString() {
return String.valueOf(value);
}
}
class StringValue extends Value {
private String value;
public String value() {
return value;
}
public StringValue(String value) {
this.value = value;
}
public String toString() {
return value;
}
}
class Operator {
public Value apply(Value x, Value y) throws ArithmeticException {
try {
var method = this.getClass().getDeclaredMethod("apply", x.getClass(), y.getClass());
return (Value) method.invoke(this, x, y);
} catch (InvocationTargetException exception) {
throw (ArithmeticException) exception.getCause();
} catch (Exception ignore) {
return null;
}
}
private IntValue apply(IntValue x, IntValue y) {
return new IntValue(x.value() / y.value());
}
private StringValue apply(StringValue x, StringValue y) {
return new StringValue(x.value() + y.value());
}
}
public class Main {
public static void main(String[] args) {
var op = new Operator();
System.out.println(op.apply(new IntValue(6), new IntValue(2)));
System.out.println(op.apply(new StringValue("a_str"), new StringValue("b_str")));
try {
System.out.println(op.apply(new IntValue(6), new IntValue(0)));
} catch (ArithmeticException exception) {
exception.printStackTrace();
}
}
}
如果您有更好的解决方案,请告诉我。