【问题标题】:Is making no attribute using inheritance proper design? Causing trouble in Serialization. Java使用继承适当的设计没有属性吗?导致序列化问题。爪哇
【发布时间】:2019-08-28 22:34:29
【问题描述】:

我是编程新手,一周前刚刚学习了继承,并且对如何设计扩展其他类的适当类有疑问。 下面的代码是将所有银行账户对象存储到 ArrayList 中的 Bank 类,这就是我在 Bank 类中扩展类 ArrayList 的原因.

问题1:Bank class属性是ArrayList。这就是我在构造函数内部调用super() 的原因。由于Bank类扩展了ArrayList,因此可以通过调用super()创建属性,我认为除了我通过调用super()创建的属性之外,bank中不需要其他私有属性。这是进行继承的正确方法吗?

问题2:由于没有属性,我通过ObjectOuputStream卡在序列化上。我想写 ArrayList(我在构造函数中通过 super() 创建的属性),但不能因为我不知道如何引用我在超级构造函数中创建的 ArrayList 属性。我尝试了 writeObject(this),但它显​​然不起作用。 如何序列化ArrayList?

问题3:如果这是实现Bank类继承的正确方法,我如何从ObjectInputStream加载ArrayList?因为没有属性,所以不知道怎么引用我在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,然后通过 this.add() 迭代并添加所有元素。

标签: java oop inheritance serialization objectoutputstream


【解决方案1】:

关于问题1,最好说Bank HAS-A ArrayList,而不是Bank IS-A ArrayList。如果扩展 ArrayList,则允许外部类修改 ArrayList 的内容。通常,当您想要扩展该对象提供的功能时,您可以扩展该对象。当您想要使用对象的方法和功能来完成您的类执行的任务时,将使用封装。您应该使用封装并维护一个包含帐户列表的私有实例变量:

public class Bank {
    private ArrayList<Account> accounts;

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

    other methods...
}

如果你想允许客户端访问和修改账户列表,你可以为它写一个getter和setter。

如果您有帐户列表的私有实例,问题 2 的解决方案很简单,您现在可以将 ArrayList 传递给 ObjectOutputStream。如果要引用 ArrayList 超类,可以将 this 对象强制转换为正确的类型:(ArrayList) this,但这对于序列化来说不是必需的。我认为您遇到的问题是 Account 类不可序列化,请确保在类头中您说 Account 类实现了 Serializable。

【讨论】:

  • 感谢您回答我的问题。我首先使用包含来创建这个 Bank 类,即遵循 Has-A 关系。但是,教授告诉我使用继承来实现这一点,以便在这个作业中获得额外的分数。所以我需要想办法用继承来实现 Bank 类。
  • 感谢您的回复。您的继承实现很好,我认为您的错误是 ArrayList 的内容也必须是可序列化的。确保在 Account 类中你说它实现了 Serializable。
  • 感谢您的回复!我完全忘记了在 ArrayList 中的其他类中实现 Serializable。但是,当没有属性时,我仍然有一些问题要从 ObjectInputStream 加载对象
  • 您应该能够创建一个ObjectInputStream 并调用readObject() 方法并将结果转换为Bank 类型
  • 是的,我可以一直做到选角。但问题是,我必须将从 ObjectInputStream 读取的对象 (ArrayList) 存储到我在构造函数 (super()) 中创建的属性 (ArrayList) 中。但我觉得没有办法引用该属性,因为我在父构造函数中创建了该属性。很抱歉解释的尴尬,但感谢您的回复。
猜你喜欢
  • 2017-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
相关资源
最近更新 更多