2

我有这个代码来自书 SCJP:

1.  class Mammal {
2.    String name = "furry ";
3.    String makeNoise() { return "generic noise"; }
4.  }
5.  
6.  class Zebra extends Mammal {
7.    String name = "stripes ";
8.    String makeNoise() { return "bray"; }
9.  }
10.
11. public class ZooKeeper {
12.   public static void main(String[] args) {
13.     new ZooKeeper().go();
14.   }
15.   
16.   void go() {
17.     Mammal m = new Zebra();
18.     System.out.println(m.name + m.makeNoise());
19.   }
20. }

运行此代码的结果是“furry bray”。

问题 1

我不明白为什么第 17 行不是: Zebra zebra2 = new Zebra();

以下每种情况的目的是什么,什么时候使用?

Mammal zebra1 = new Zebra();

对比

Zebra zebra2 = new Zebra();   

问题2

为什么类中的变量name = "stripes"会被类中的变量Zebra覆盖?我希望相反:来自子类的变量将覆盖来自超类的变量。name = "furry"Mammal

4

3 回答 3

6

答案 1

Mammal zebra1 = new Zebra();用于表明您可以将派生类的对象分配给父类类型的变量。这也是. Mammal m_ 可以保存类的对象或从 . 派生的任何类。LionmmMammalMammal

答案 2

这也与继承有关。当您打印出a 的m.name位置时,您将获得该类的该属性的值。您不能通过继承覆盖变量,只能覆盖方法。如果您向两个类都添加一个方法,两者都会返回,则返回。mMammalMammalgetName()namem.getName()"stripes"

于 2012-08-27T08:12:24.860 回答
1
  1. 因为Zebra Mammal

  2. 变量不能被覆盖。如果将第 15 行更改为:

    System.out.println(((Zebra) m).name + m.makeNoise());

    你会得到stripes bray

于 2012-08-27T08:13:59.330 回答
1

答案1:取决于你想要什么。在这种情况下,它并不那么明显。但有时您只希望对象不属于 1 类或 2 类。假设您有一个斑马而不是哺乳动物的方法,并且您想使用该方法,那么您的对象需要不属于斑马类而不是哺乳动物。但是如果有一个第三方类的方法只接受哺乳动物变量,那么你必须传递一个哺乳动物对象。

Answer2:m.name 是哺乳动物的变量(不能被覆盖),m.makeNoise() 是一个方法,在 Zebra 中被覆盖。

于 2012-08-27T08:20:28.513 回答