Почему поле суперклассов отличается при вызове из подкласса?

Почему узлы полей возвращают разный размер при вызове из подкласса

не должны ли подклассы иметь доступ к своим полям суперклассов?

Вот воспроизводимый пример:

Manager.java

import java.util.HashMap;

public class Manager {
    protected HashMap<Integer,Node> nodes = new HashMap<>();

    public HashMap<Integer, Node> getNodes() { return nodes; }

    public void addNode(Node node){
        nodes.put(nodes.size(),node);
    }

    public static void main(String[] args) {
        Manager manager = new Manager();
        manager.addNode(new Node());
        System.out.println("(from Manager) manager.nodes.size() = " + manager.nodes.size());
        manager.getNodes().get(0).printNodesSize();
    }
}

Node.java

public class Node extends Manager {
    public void printNodesSize() {
        System.out.println("(from Node) manager.nodes.size() = " + super.nodes.size());
    }
}

Системный выход:

(from Manager) manager.nodes.size() = 1
(from instanced Node) manager.nodes.size() = 0

Process finished with exit code 0

Я предлагаю вам выполнить это с помощью отладчика, чтобы вы могли проверять все свои объекты после каждой строки кода. Я подозреваю, что Map хранит не то, что вы думаете.

Dawood ibn Kareem 17.05.2022 23:32
manager — это экземпляр, отличный от Node, который был добавлен к нему, то есть оба имеют разные карты — manager.nodes — это не тот же список, что и manager.getNodes().get(0).nodes, и к последнему не было добавлено ни одного Node (на самом деле это немного не так традиционно, чтобы иметь расширение Node Менеджер)
user16320675 17.05.2022 23:59

Да, я думаю, мне нужно вернуться и просмотреть, как работает расширение классов. Я пока избавлюсь от него и просто вызову информацию статически. Благодарю вас!

Fmxerz 18.05.2022 00:46
Основы программирования на Java
Основы программирования на Java
Java - это высокоуровневый объектно-ориентированный язык программирования, основанный на классах.
Концепции JavaScript, которые вы должны знать как JS программист!
Концепции JavaScript, которые вы должны знать как JS программист!
JavaScript (Js) - это язык программирования, объединяющий HTML и CSS с одной из основных технологий Всемирной паутины. Более 97% веб-сайтов используют...
3
3
28
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема, с которой вы столкнулись, не имеет ничего общего с наследованием. Вызов:

manager.getNodes()

вернет Map<Integer, Node> (проверьте собственное определение метода в классе Manager), который содержит только один элемент с индексом 1 (потому что вы определяете ключ как nodes.size()+1).

Следовательно, когда вы вызываете manager.getNodes().get(0), вы получаете элемент null (карта не содержит элементов с ключом 0).

Если вы замените .get(0) на .get(1), это сработает.

Примечание: ваш дизайн не очень чистый. Класс Manager (родительский) содержит карту Nodes, которая является его собственным потомком. Ребенок (Node) должен знать своего родителя (Manager), но не наоборот.

Редактировать

Печать super.nodes.size() равна 0, потому что вы не указываете на экземпляр Manager, на который, как вам кажется, вы указываете.

Когда вы делаете new Node() (узел, который вы добавляете к своему manager), вы создаете new Manager(), у которого по умолчанию есть пустая карта.

Поэтому, когда вы вызываете super.nodes.size(), ваш super — это не manager, как вы думаете, а другой экземпляр Manager, который вы создали при выполнении new Node(), к которому вы никогда ничего не добавляли.

Опять же, я предлагаю вам проверить мое примечание выше и пересмотреть свой дизайн.

Спасибо, я обновлю свой вопрос. Это была ошибка при создании MRE. Размер узлов в соответствии с экземпляром узла по-прежнему равен 0.

Fmxerz 17.05.2022 23:34

@Fmxerz, пожалуйста, проверьте мое редактирование

Matteo NNZ 17.05.2022 23:40

Спасибо, это заняло у меня минуту, но я думаю, что понимаю, о чем вы говорите. Когда вы создаете подкласс, он неявно создает суперкласс? Причина, по которой я структурировал его таким образом, заключается в том, что узлам нужен доступ к информации о родственных узлах. Раньше я обращался к узлам как к статическому полю в Manager. Я заметил, что мог бы использовать super для получения этой информации, но это превращается в головную боль и множество изменений в моем полном коде.

Fmxerz 18.05.2022 00:25

Другие вопросы по теме