5

在 Java 中,我有一个类Num,以及一些扩展的类Num,比如Num_intNum_double。我想知道一种方法是否可以识别给定Num对象是否为 a 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( );. 这可能吗?

谢谢。

4

5 回答 5

3
if (x instanceof Num_int) {
  System.out.println("int");
} else {
  System.out.println("other");
}
于 2012-12-14T18:10:16.840 回答
3

如果您想要多态行为,则使测试方法成为 Num 类的可覆盖方法。

重载的方法不会根据参数的运行时类型进行多态解析。它们在编译时根据声明的参数类型进行解析。

于 2012-12-14T18:11:52.457 回答
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()
}
于 2012-12-14T18:10:03.760 回答
1

The problem is that method signatures are binded at compile time in Java, so the declared type determines which method is called.

See also the puzzler "Making a Hash of It" in the book Java Puzzlers.

You could use double-dispatching and the Visitor pattern. It would look something like this:

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

The Num_int.accept(...) and Num_double.accept(...) methods would both look like this:

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

Even though these methods are almost identical, it's important that the method isn't extracted into the parent class. I'd go so far as to make it abstract in the parent class:

public class Num {
    public abstract void accept(Num_visitor);
}

From within class Num, this is of declared type Num. If the accept method were defined here, the compile-time binding would be to signature visit(Num) - giving you the same original problem all over again.

Lastly, the Num_printer would look like this:

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

}
于 2012-12-14T18:18:01.347 回答
0

您可以使用instanceof运算符。阅读本文档中的“类型比较运算符 instanceof ”部分。

if (x instanceof Num_int) {
  // do something
} else if (x instanceof Num_double) {
  // do something else
}
于 2012-12-14T18:12:07.170 回答