Nano Hash - криптовалюты, майнинг, программирование

Передача по значению и полиморфизм

Я новичок в программировании и не понимаю, почему этот код печатает 200 вместо 206. Метод перемещения в классе Cat переопределяет метод перемещения в классе Animals. Почему переменная экземпляра «местоположение» в Animals не изменяется на 206 после вызова метода в строке 2? Однако, когда я удаляю метод в классе 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;
    }
}

  • Вы использовали функцию отладки? Попробуйте... тогда вы увидите, по какому именно пути идет ваше исполнение. 18.09.2015
  • Удалить int location = 400 из класса Cat. 18.09.2015

Ответы:


1
a.move(6); // line 2
System.out.println(a.location);

В первой строке вы выполняете метод в Cat, что означает, что вы изменяете переменную класса Cat.

Во второй строке вы печатаете переменную из Animal.

Вы не можете переопределить переменные в Java. Только методы.

И что вы сделали, так это затенили переменную экземпляра location в Cat, и когда вы изменили это в своем классе Cat, вы больше не указываете на Animal. Когда вы удаляете эту переменную в классе Cat, вы имеете в виду класс Animal.

18.09.2015

2

Проблема в том, что вы определяете местоположение как в суперклассе, так и в подклассе. Следовательно, есть две разные переменные. Cat.move изменяет Cat.location. Однако, если вы используете ссылку на базовый класс для получения местоположения, вы получаете местоположение экземпляра животного вместо местоположения кошки.

Один из способов исправить это — пометить местоположение как защищенное в Animal и инициализировать его значение (200 или 400) в конструкторе по умолчанию каждого класса.

18.09.2015

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;
    }
}
18.09.2015
  • Или просто прекратите слежку в классе кошек :) 18.09.2015
  • @sᴜʀᴇsʜᴀᴛᴛᴀ лучше использовать метод получения: D 18.09.2015
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..