0

使用以下代码:

public class Animal {
   ....// class stuff here
}

public class Cat extends Animal {
   ....// class stuff here
}

尝试创建新的 Cat 对象时,有什么区别?:

    Cat myCat = new Cat(); //and
    Animal myCat = new Cat();

我以前读过你应该在左边声明最通用的列表(即

List<String> = new LinkedList<String>();) 因此,如果您想更改实现以改用 ArrayList,则需要更改的代码更少。

是否在所有情况下都应始终在 laft 上声明最通用(最不具体)(在这种情况下Animal myCat = new Cat();)?

4

5 回答 5

2

创建的内容没有区别。唯一的区别在于引用的类型。如果你引用了 Animal,并尝试使用 Cat 中不存在于 Animal 中的方法,编译器会报错。如果你调用一个在 Cat 中被覆盖的方法(注意:与重载不同),它会正确调用 Cat 的方法,即使引用是 Animal 的。

于 2012-10-10T11:45:50.527 回答
1

最具体的就是相关的。否则,所有变量都是Object.

根据经验,如果您的逻辑需要调用特定于 的方法Cat,那么您应该将变量声明为Cat。如果没有,那么它应该是一个Animal如果你需要任何方法Animal,依此类推。

于 2012-10-10T11:45:03.270 回答
1

假设我们有以下代码

public class Animal {
  public void doSomething() {
       // ...
  }
}

public class Cat extends Animal {
  public void miau() {
       // ...
  }
}

不同的是

Cat myCat1 = new Cat(); //and
Animal myCat2 = new Cat();
myCat1.miau(); //ok
myCat1.doSomething(); //ok
myCat2.miau(); // doesn't compile
myCat2.doSomething(); // ok

这取决于您打算使用哪个站点。一个例子是一个列表。如果您知道您只将 Cat's 放入此列表,请将其声明为:

ArrayList<Cat> list = new ArrayList<Cat>();

但是如果你知道你放了各种各样的动物,你需要做如下声明

ArrayList<Animal> list = new ArrayList<Animal>();

您还可以执行以下操作:

ArrayList<Object> list = new ArrayList<Object>();

但这不是好的编码风格。因为如果你想调用一个方法,miau你首先需要检查你要调用它的元素是否是Cat. 然后你甚至需要投射它。

于 2012-10-10T11:45:15.157 回答
1

和...之间的不同

Cat myCat = new Cat(); //and 
Animal myCat = new Cat();

是前者是针对具体实现进行编程,而后者是针对接口/超类型进行编程。

后一种方法是首选,这样实际的运行时对象就不会绑定在您的代码中。并且使用你的动物类的类不必知道实际的动物对象(除了一只猫之外,它可能是相当大的数量)。

因此,您可以 animal.makeSound()使用后者,这使您可以多态地引用动物(在您的情况下是猫/任何其他动物)

于 2012-10-10T11:51:03.650 回答
0

只是用外行的语言解释,这一切都取决于你想要什么,我将举一个非常简单的例子,因为你可以从我提供的链接中获得其余的解释。

  • 假设你想计算你的篮子里有多少只猫,那么你当然不能用第二种情况。你必须创建一个List<Cat>并将Cat引用存储到它们中。因为Animal引用也可以指向Dog正确的?因此,一个List<Animal>可以容纳一个Dog..所以,您可能无法正确计算 Cat.. 或者,您可以得到,但需要做更多的工作..

  • 如果您只想了解Animal一般信息,例如您总共拥有多少种不同类型的动物,您可以愉快地使用第一个..使用Animal引用创建一个对象..它可以容纳您所有的动物..

于 2012-10-10T11:49:36.037 回答