Запутался в переопределениях методов java

425
14 июня 2017, 01:11

Разрабатываю приложение на android - ключевая задача: работа с базой данных.

Есть абстрактный класс Catalog справочник, от него наследуются классы справочников Goods товары, Units единицы измерения. В суперклассе определен метод creationString()

public String creationString() {
    String creationString = super.creationString();
    creationString += COL_NAME + " TEXT);";
    return creationString;
}

метод нужен для формирования строки создания таблицы sqlite базы данных. Класс Catalog наследуется от еще более абстрактного класса Table в котором creationString начинается со слов CREATE TABLE и т.д.

В классе Catalog метод creationString() перегружается 2 раза

public String creationString(boolean hasIerarchy) {
    String creationString = this.creationString();
    if (hasIerarchy) {
        creationString = trimEndCreationString(creationString);
        creationString += ", "+COL_PARENT+" INTEGER"
                        +", "+COL_ISFOLDER+" NUMERIC);";
    }
    return creationString;
}

и

    public String creationString(boolean hasIerarchy, boolean hasOwner) {
    String creationString = this.creationString(hasIerarchy);
    if (hasOwner) {
        creationString = trimEndCreationString(creationString);
        creationString += ", "+COL_OWNER+" INTEGER);";
    }
    return creationString;
}

То есть в перегруженных вызовах вызывается предыдущая версия метода с меньшим количеством агрументов, чтобы добавить к строке создания новые поля. В классе Goods - метод creationString() - переопределяется.

public String creationString() {
    String creationString = super.creationString(true);
    creationString = trimEndCreationString(creationString);
    creationString += ", " + COL_FNAME + " TEXT, "
            + COL_ART + " TEXT, "
            + COL_BASE_UNIT + " INTEGER, "
            + COL_TYPE + " INTEGER);";
    return creationString;
}

В этом методе вызывается версия метода суперкласса с одним булевым аргументом, чтобы добавить колонку родителя.

Проблема в том, что когда в этом методе суперкласса вызывается creationString() без агрументов - вызывается переопределнный creationString() из класса Goods И я получаю ошибку StackOverFrow Как в таком случае четко определить чтобы вызывался creationString() из конкретного класса, а не переопределенная версия?

Answer 1

Класс Catalog не переопределяет метод родителя, а создает новый перегруженный метод, так как для overriding есть определенные правила и одно из них это неизменность сигнатуры метода, в которую входят параметры метода. Вот Ваш класс Goods переопределяет метод супер-предка класса**Table**, а не методы Catalog.

Поэтому когда у объекта класса Goods который хранится в переменной типа Table, происходит вызов метода createTable(), то согласно полиморфизму и динамическому связыванию вызывается переопределенный метод класса Goods.

Дальше, из этого метода вызывается, метод класса Catalog и в нем идет вызов метода родителя this.creationString(), но опять срабатывает полиморфизм и вызывается метод класса Goods. Начинается бесконечный цикл который приводит к StackOverFlowError

Чтобы решить эту проблемму, можно в классе Catalog сменить this.creationString() на super.creationString() тогда явно вызовется метод класса Table.

У Вас явные проблеммы с архитектурой и ее надо пересмотреть. Потому как предложенное мной решение лишь усугубит дальнейшие проблемы.

READ ALSO
Сканирование из консоли (java)

Сканирование из консоли (java)

Пусть в консоли вводят {1, 2, 3, 4}, причем, я не знаю количество чисел, я хочу работать с этим, как с массивом целых чисел, но понятно , что я не могу...

323
Java Swing графика double-координаты

Java Swing графика double-координаты

Graphics: drawOval(int x, int y, int width, int height) - существует ли аналог, но только с нецелыми координатами?

323
Входной аудио поток

Входной аудио поток

Здравствуйте, я захватываю звук с помощью микрофонаИ сигнал получаю как массив байтов

584
Progressbar выкидывает java.lang.NullPointerException, где ошибка?

Progressbar выкидывает java.lang.NullPointerException, где ошибка?

Предполагаю что дело в модификаторах доступа, но не могу понять почему pbHealthsetProgress(a) выдает NullPointerException?

300