在java中与参考强制转换和扩展w.r.t对象混淆

时间:2010-01-23 13:16:26

标签: java

对于原语和他们的Wrappers,我理解了扩展的概念。但是对于其他对象,我对扩展和隐式转换感到困惑。例如

       Class Animal{
        }

        Class Dog extends Animal{

         public static void main(args String[]){

         Dog d = new Dog();
         d.go(d);
        }

       void go(Animal a){    }
      }

编辑:问题是哪一个首选加宽或转换?为什么?

2 个答案:

答案 0 :(得分:1)

(在我看来)如果不需要铸造那么就不要这样做。您的代码将更具可读性。

特别是语法:

 d.go(d);

更简洁,和

一样正确
d.go((Animal)d);

基本上,在我第一次尝试回答您的问题时,请利用我在下面描述的原因进行扩展。


嗯,这取决于您希望代码完成的任务。

如果你想要一个可以处理任何动物,狗或其他类型的功能,那么你应该把动物作为输入。

如果你想要一个只需要Dogs的东西,或者只是作为一个以Dogs为输入的操作才有意义的函数,那么你应该把狗作为输入。

编辑:也许一个更人为的例子将说明为什么这不是一个简单的uinversal答案的问题。在Java中,所有对象都是Object的子对象,因此,可以编写任何方法,使其采用参数Object foo

有时这可能很有用,但它的用例非常严格,只限于Object上定义的方法。

假设您知道Dog,这也是Object。您可能希望将某些属性特定传递给Dog,而不是将Object的实例作为Dog传递。基本上,如果你需要确保某个函数的参数符合某个契约,你应该将参数限制为符合的类型 - 略有不同:如果你需要知道它是一个狗,它声明它是一个狗

作为一般规则,您(我认为)应该选择符合您需要履行的任何合同的“最广泛”类型。 如果您需要知道它是动物宣称它是动物

答案 1 :(得分:0)

我同意马克的说法,这取决于。我使用经验法则,基本上只是说声明类型到子类型的转换是“坏”。所以如果在你的方法的某个地方

void go(Animal a){ ... }

你需要像

这样的演员表

Dog d = (Dog) a;

你绝对应该(如果可能的话)将Animal类型的参数a更改为Dog类型的参数。如果该方法适用于Animal的所有子类型而没有强制转换,则保持原样。