Является ли создание атрибута без использования наследования правильным дизайном? Вызывает проблемы в сериализации. Джава

Я новичок в программировании, и я только что изучил наследование неделю назад, и у меня есть вопрос о том, как разработать правильный класс, который расширяет другой класс. Ниже приведен код Банк Класс, в котором весь объект банковского счета хранится в ArrayList, поэтому я расширяю класс ArrayList в классе Bank.

Вопрос 1: Атрибут Банковский класс равен ArrayList. Вот почему я вызываю super() внутри конструктора. Поскольку атрибут можно создать, вызвав super(), потому что класс Bank расширяет ArrayList, я подумал, что в банке не нужен никакой другой закрытый атрибут, кроме атрибута, который я создал, вызвав super(). Это правильный способ сделать наследование?

Вопрос 2: Поскольку атрибута нет, я застрял на сериализация через ObjectOuputStream. Я хочу написать ArrayList (атрибут, который я создал, выполнив super() в конструкторе), но не могу, потому что я не знаю, как ссылаться на атрибут ArrayList, который я создал в суперконструкторе. я пробовал writeObject(this), но это явно не сработало. Как можно сериализовать ArrayList?

Вопрос 3: Если это правильный способ реализовать наследование класса Bank, как я могу загрузить ArrayList из ObjectInputStream? Поскольку атрибута нет, я не знаю, как обратиться к атрибуту, который я делаю в super(), поэтому я сделал такую ​​вещь, как

this = (ArrayList)ois.readObject()

Но это не сработало... Как я могу загрузить ArrayList с помощью десериализации, когда атрибута нет?

public class Bank extends ArrayList<Account> implements Serializable{
    //no attribute

    public Bank(){
        super();
    }

    //other methods...

    public void saveToBinary() throws IOException{
        FileOutputStream fos = new FileOutputStream("Bank_Account_Inherit_Binary.txt");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(this);//can't do this
        oos.flush();
        oos.close();
    }

    public void loadFromBinary() throws IOException, ClassNotFoundException{
        FileInputStream fis = new FileInputStream("Bank_Account_Inherit_Binary.txt");
        ObjectInputStream ois = new ObjectInputStream(fis);
        Object object = ois.readObject();
        this = (ArrayList<Account>)object;//not working b/c "this" is final variable
    }
}

Для тех из вас, кому интересно, как решить эту проблему, вы можете просто привести объект из файла к ArrayList<Account>, а затем выполнить итерацию и добавить все элементы, выполнив this.add().

XYZ 12.03.2021 10:38
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
1
72
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Что касается вопроса 1, было бы лучше сказать, что Банк ИМЕЕТ ArrayList, а не Банк ЕСТЬ-A ArrayList. Если вы расширяете ArrayList, вы позволяете внешним классам изменять содержимое ArrayList. Обычно вы расширяете объект, когда хотите расширить возможности, предлагаемые этим объектом. Инкапсуляция используется, когда вы хотите использовать методы и возможности объекта для выполнения задач, которые выполняет ваш класс. Вы должны использовать инкапсуляцию и поддерживать закрытую переменную экземпляра, содержащую список учетных записей:

public class Bank {
    private ArrayList<Account> accounts;

    public Bank() {
        accounts = new ArrayList<Account>();
    }

    other methods...
}

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

Если у вас есть частный экземпляр списка учетных записей, решение вопроса 2 простое: теперь вы можете передать ArrayList в ObjectOutputStream. Если вы хотите сослаться на суперкласс ArrayList, вы можете привести объект this к нужному типу: (ArrayList) this, но это не обязательно для сериализации. Я думаю, что проблема, с которой вы столкнулись, заключается в том, что класс Account не сериализуем, убедитесь, что в заголовке класса указано, что класс Account реализует Serializable.

Спасибо, что ответили на мой вопрос. Сначала я использую включение для создания этого класса Bank, который следует отношению Has-A. Однако профессор сказал мне реализовать это с помощью наследования, чтобы получить дополнительные баллы за это задание. Поэтому мне как-то нужно выяснить, как реализовать класс Bank с использованием наследования.

XYZ 07.04.2019 20:55

Спасибо за ответ. Ваша реализация наследования в порядке, я думаю, что ваша ошибка в том, что содержимое ArrayList также должно быть Serializable. Убедитесь, что в классе Account вы говорите, что он реализует Serializable.

chiragzq 07.04.2019 21:15

Спасибо за ответ! Я совершенно забыл о реализации Serializable в другом моем классе, который находится в ArrayList. Однако у меня все еще есть вопрос для загрузки объекта из ObjectInputStream, когда нет атрибута

XYZ 08.04.2019 19:13

Вы должны иметь возможность создать ObjectInputStream и вызвать метод readObject() и привести результат к типу Bank

chiragzq 08.04.2019 21:45

Да, я могу сделать до кастинга. Но проблема в том, что я должен сохранить объект (ArrayList), который я прочитал из ObjectInputStream, в атрибут (ArrayList<Account>), который я создал в конструкторе (super()). Но я чувствую, что нет никакого способа сослаться на этот атрибут, потому что я создал атрибут в конструкторе родителей. Извините за сумбурное объяснение, но спасибо за ответ.

XYZ 08.04.2019 22:43

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