【问题标题】:Pass-by-value & polymorphism [duplicate]值传递和多态性
【发布时间】:2015-12-15 14:57:29
【问题描述】:

我对编程还很陌生,不明白为什么这段代码会打印 200 而不是 206。Cat 类中的 move 方法覆盖 Animals 类中的 move 方法。为什么第 2 行方法调用后 Animals 中的 'location' 实例变量没有变为 206?但是,当我删除类 Cat 中的方法时,实例变量 DOES 变为 206。这背后的逻辑是什么?

public  class Animals {
   int location = 200; //line 1

   public void move(int by) {
       location = location+by;
   }

    public final static void main (String...args) {
        Animals a = new Cat();
        a.move(6); //line 2
        System.out.println(a.location); //200, but should print 206 in my opinion
    }
}

class Cat extends Animals {
    int location = 400;

    @Override
    public void move(int by) { //if this method is removed, a.location prints 206
        location = location+by;
    }
}

【问题讨论】:

  • 你使用调试功能了吗?试一试......然后你会看到你的执行到底是哪条路径。
  • 从类 Cat 中删除 int location = 400

标签: java inheritance polymorphism pass-by-value


【解决方案1】:
a.move(6); // line 2
System.out.println(a.location);

在第一行中,您正在执行 Cat 中的方法,这意味着您正在修改 Cat 类的变量。

在第二行中,您正在打印来自Animal 的变量。

您不能在 Java 中覆盖变量。只有方法。

而您所做的是在 Cat 上隐藏了实例变量 location,当您在 Cat 类中修改它时,您不再指向 Animal。当您在 Cat 类中删除该变量时,您指的是Animal Class。

【讨论】:

    【解决方案2】:

    问题是您在超类和子类中都定义了位置。因此,有两个不同的变量。 Cat.move 修改 Cat.location。但是,如果您使用基类引用来获取位置,您将获得动物的实例位置而不是猫的位置。

    修复它的一种方法是在 Animal 中标记位置受保护并在每个类的默认构造函数中初始化其值(200 或 400)。

    【讨论】:

      【解决方案3】:

      强制打印出你的对象实际上是Cat

          System.out.println(((Cat)a).location); //it prints 406
      

      解决这个问题的最好方法是正确使用Java,你不应该直接调用变量,而应该调用方法。

      这是获得您想要的更好的方法:

      public  class Animals {
          int location = 200; //line 1
      
         public void move(int by) {
            location = location+by;
         }
      
         public int getLocation(){
          return location;
         }
      
          public final static void main (String...args) {
              Animals a = new Cat();
              a.move(6); //line 2
              System.out.println((a).getLocation()); //note we are now calling a getter method not the variable itself
          }
      }
      
      class Cat extends Animals {
          int location = 400;
      
      
         public int getLocation(){
          return location;
         }
      
      
          public void move(int by){
             location = location+by;
          }
      }
      

      【讨论】:

      • 或者只是在 Cat 类中停止阴影 :)
      • @sᴜʀᴇsʜᴀᴛᴛᴀ 最好使用 getter 方法:D
      猜你喜欢
      • 1970-01-01
      • 2013-04-21
      • 1970-01-01
      • 2012-04-27
      • 2011-05-04
      • 2017-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多