2010-01-23 94 views
2

使用基元和它们的包装器我理解了扩展的概念。但就其他对象而言,我对扩展和隐式Casting感到困惑。作为例子与参考投射混淆并在java中扩展w.r.t对象

 Class Animal{ 
     } 

     Class Dog extends Animal{ 

     public static void main(args String[]){ 

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

     void go(Animal a){ } 
     } 

编辑:问题是哪一个是首选的扩大或铸造,为什么?

+2

问题是? – 2010-01-23 13:19:52

回答

1

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

尤其是语法:

d.go(d); 

更加简洁,而且同样正确的,因为

d.go((Animal)d); 

基本上采取的原因扩大优势下面我介绍我的第一次尝试回答你的问题。


那么,这取决于你想要代码完成什么。

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

如果你想要一个只需要狗只有的东西的功能,或者只有把狗作为输入的操作才有意义,那么你应该把狗当作输入。

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

有时候这可能是有用的,但它的使用情况确实非常严格,您仅限于Object上定义的方法。

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

作为一般规则,您应该(在我看来)选择符合您需要履行的任何合同的“最宽”类型。 如果你需要知道它是一个动物声明它是一个动物

+0

我不明白你想说什么。我在上面的例子中问了哪一个是prefererd。 – GuruKulki 2010-01-23 13:29:00

+0

@gurukulki,任何“偏好”取决于你的代码需要完成什么(这里没有普遍的答案)。我举了什么时候扩大优先的例子,什么时候狭窄是首选。 – 2010-01-23 13:33:18

+0

但我问什么时候扩张是先发制人,并且首选是铸造 – GuruKulki 2010-01-23 13:34:57

0

我同意马克的看法。我使用的经验法则基本上只是说声明类型转换为子类型是“不好”的。所以,如果某处你的方法

void go(Animal a){ ... }

你需要像

Dog d = (Dog) a;

铸造你绝对应该(如果可能)改变的Animal类型的参数类型狗的参数。如果该方法适用于所有Animal的子类型而没有投射,则保持原样。