在Java中,我有一个类Num
,以及一些扩展Num
的类,如Num_int
和Num_double
。
我想知道方法是否可以识别给定的Num
对象是否为Num_int
。
我有以下代码:
void test(Num_int x) {
System.out.println("int");
} // test
void test(Num x) {
System.out.println("other");
} // test
Num_int A = new Num_int( );
Num B = new Num_int( );
Num C = new Num_double( );
test(A); // prints "int"
test(B); // prints "other"
test(C); // prints "other"
不幸的是,当给出A作为参数时,方法“test”仅打印“int”。
当B通过时,我还不能打印“int”,因为B是通过Num B = new Num_int( );
创建的。这可能吗?
感谢。
答案 0 :(得分:3)
if (x instanceof Num_int) {
System.out.println("int");
} else {
System.out.println("other");
}
答案 1 :(得分:3)
如果您想要多态行为,那么使测试方法成为Num类的可覆盖方法。
根据参数的运行时类型,不会以多态方式解析重载方法。它们在编译时根据声明的参数类型得到解决。
答案 2 :(得分:2)
这可以使用instanceof
运算符和强制转换来完成。但是,这是一种糟糕的编程习惯。
更好的选择是让test()
成为final
的非Num
成员,并在每个类中适当地覆盖它。然后你只需要调用A.test()
,Java的动态调度将为你处理一切。
public class Num {
public void test() {
System.out.println("other");
}
}
public class Num_int extends Num {
public void test() {
System.out.println("int");
}
}
public class Num_double extends Num {
// inhertis Num.test()
}
答案 3 :(得分:1)
问题是方法签名在Java编译时被绑定,因此声明的类型决定了调用哪个方法。
参见书籍Java Puzzlers中的益智游戏“制作一个哈希”。
您可以使用双重调度和访客模式。它看起来像这样:
Num_int A = new Num_int( );
Num B = new Num_int( );
Num C = new Num_double( );
Num_printer p = new Num_printer();
A.accept(p);
B.accept(p);
C.accept(p);
Num_int.accept(...)
和Num_double.accept(...)
方法看起来都是这样的:
public class Num_int extends Num {
public void accept(Num_visitor v) {
v.visit(this); // from this scope, `this` has a declared type of `Num_int`
// so at compile time this is binded to signature visit(Num_double)
}
}
public class Num_double extends Num {
public void accept(Num_visitor v) {
v.visit(this); // from this scope, `this` has a declared type of `Num_double`
// so at compile time this is binded to signature visit(Num_double)
}
}
尽管这些方法几乎完全相同,但重要的是该方法不会被提取到父类中。我甚至在父类中将其抽象化:
public class Num {
public abstract void accept(Num_visitor);
}
在班级Num
内,this
声明为Num
。如果此处定义了accept
方法,则编译时绑定将是签名visit(Num)
- 再次为您提供相同的原始问题。
最后,Num_printer
看起来像这样:
public class Num_printer implements Num_visitor {
public void visit(Num_int n) {
System.out.println("int");
}
public void visit(Num_double n) {
System.out.println("double");
}
}
答案 4 :(得分:0)
您可以使用instanceof
运算符。阅读this document中的“类型比较运算符实例”部分。
if (x instanceof Num_int) {
// do something
} else if (x instanceof Num_double) {
// do something else
}