Является ли создание атрибута без наследования надлежащего дизайна?Причинение неприятностей в сериализации.Джава - PullRequest
1 голос
/ 07 апреля 2019

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

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

Вопрос 2: Поскольку атрибута нет, я застрял на сериализации через ObjectOuputStream. Я хочу написать ArrayList (атрибут, который я создал, выполнив super() в конструкторе), но не могу, потому что я не знаю, как ссылаться на атрибут ArrayList, который я создал в супер-конструкторе. Я попытался написатьObject (это), но это не сработало, очевидно. Как можно сериализовать 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
    }
}

1 Ответ

1 голос
/ 07 апреля 2019

Относительно вопроса 1 было бы лучше сказать, что у банка есть ArrayList, а не у банка IS-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.

...