对于原语和他们的Wrappers,我理解了扩展的概念。但是对于其他对象,我对扩展和隐式转换感到困惑。例如
Class Animal{
}
Class Dog extends Animal{
public static void main(args String[]){
Dog d = new Dog();
d.go(d);
}
void go(Animal a){ }
}
编辑:问题是哪一个首选加宽或转换?为什么?
答案 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
的所有子类型而没有强制转换,则保持原样。