Я новичок в программировании, и я только что изучил наследование неделю назад, и у меня есть вопрос о том, как разработать правильный класс, который расширяет другой класс. Ниже приведен код Банк Класс, в котором весь объект банковского счета хранится в 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
}
}
Что касается вопроса 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 с использованием наследования.
Спасибо за ответ. Ваша реализация наследования в порядке, я думаю, что ваша ошибка в том, что содержимое ArrayList также должно быть Serializable. Убедитесь, что в классе Account вы говорите, что он реализует Serializable.
Спасибо за ответ! Я совершенно забыл о реализации Serializable в другом моем классе, который находится в ArrayList. Однако у меня все еще есть вопрос для загрузки объекта из ObjectInputStream, когда нет атрибута
Вы должны иметь возможность создать ObjectInputStream
и вызвать метод readObject()
и привести результат к типу Bank
Да, я могу сделать до кастинга. Но проблема в том, что я должен сохранить объект (ArrayList), который я прочитал из ObjectInputStream, в атрибут (ArrayList<Account>), который я создал в конструкторе (super()). Но я чувствую, что нет никакого способа сослаться на этот атрибут, потому что я создал атрибут в конструкторе родителей. Извините за сумбурное объяснение, но спасибо за ответ.
Для тех из вас, кому интересно, как решить эту проблему, вы можете просто привести объект из файла к ArrayList<Account>, а затем выполнить итерацию и добавить все элементы, выполнив this.add().