繁体   English   中英

识别扩展类对象

[英]Recognizing extended class object

在Java中,我有一个类Num ,以及一些扩展Num类,如Num_intNum_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( ); 这可能吗?

谢谢。

if (x instanceof Num_int) {
  System.out.println("int");
} else {
  System.out.println("other");
}

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

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

这可以使用instanceof运算符和强制转换来完成。 但是,这是一个糟糕的编程习惯。

更好的选择是使test()成为Num的非final成员,并在每个类中适当地覆盖它。 然后你只需调用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()
}

问题是方法签名在Java编译时被绑定,因此声明的类型决定了调用哪个方法。

另请参阅Java Puzzlers一书中的益智游戏“Make a Hash of It”。

您可以使用双重调度和访客模式。 它看起来像这样:

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

在类Numthis是声明的类型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");
    }

}

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

if (x instanceof Num_int) {
  // do something
} else if (x instanceof Num_double) {
  // do something else
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM