传值和多态

Pass-by-value & polymorphism

我是编程新手,不明白为什么这段代码打印 200 而不是 206。class Cat 中的移动方法覆盖了 class Animals 中的移动方法。为什么Animals中的'location'实例变量在第2行方法调用后没有变成206?但是,当我删除 class Cat 中的方法时,实例变量确实变为 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;
    }
}
a.move(6); // line 2
System.out.println(a.location);

第一行你在执行Cat中的方法,也就是说你在修改Cat class.

的变量

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

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

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

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

修复它的一种方法是在 Animal 中标记位置受保护并在每个 class.

的默认构造函数中初始化其值(200 或 400)

强制打印出你的对象实际上是 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;
    }
}