Java多态:带有额外字段的子类

时间:2014-04-15 21:57:29

标签: java polymorphism

我已经用Java编程了一段时间,但主要只是小命令行程序。现在我有了一个更大的项目,我试图找到一个体面的设计。 它是一个小型数据库查找/更新工具。 我有三种不同类型的表,但表之间有几个共享列。 EG:

表1(FieldName,FieldId,FieldValue,AppName,AppId,AppValue)
表2(FieldName,FieldId,FieldValue,UpdatedBy)
表3(FieldName,FieldId,FieldValue,UpdatedDate)

我希望有这样的东西:

abstract class BaseTable { FieldName FieldId FieldValue }

class Table1 extends?implements? BaseTable { FieldName FieldId FieldValue AppName AppId AppValue }

class Table2 extends?implements? BaseTable { FieldName FieldId FieldValue UpdatedBy }

class Table3 extends?implements? BaseTable { FieldName FieldId FieldValue UpdatedDate }

我会读取参数来确定我需要哪种类型的表,但基本上我想做这样的事情:

BaseTable bt = null;
if (tableType = Table1)
    bt = new Table1();
else if (tableType = Table2)
    bt = new Table2();
else if (tableType = Table3)
    bt = new Table3();

bt.doSpecificStuff();
HashMap<String,BaseTable> map = new HashMap<String,Table1>();
map.put(someString, bt);

这里有几个问题:
我无法访问子类&#39;使用此设计的额外字段。
2.我不想使用Table1 t1 = new Table1();,因为由于参数类型不同,我不能使用常用方法。
3.当我尝试创建哈希映射来保存对象的实例时,我收到编译错误说:

Type mismatch: cannot convert from HashMap<String,Table1> to HashMap<String,BaseTable>

基本上,我的设计似乎存在一些问题,我无法想出解决这些问题的方法。我不想创建三个不相关的类,因为我觉得它违背了OOO的目的,我的程序保证它的用途。此外,这必须是一个简单而优雅的解决方案的常见问题,但我还没有找到很多明确处理其子类中具有额外字段的对象。 任何人都可以建议我的程序更好的设计,以某种方式允许我访问子类字段,同时能够实例化基类对象类型?

2 个答案:

答案 0 :(得分:1)

您应该将代码中的倒数第二行更改为:

HashMap<String,BaseTable> map = new HashMap<String,BaseTable>();

然后,您可以将子类的任何实例放入地图中。从那里,如果您需要执行特定于类的操作,您可以使用instanceof运算符并转换您的对象:

if (bt instanceof Table1) {
    Table1 tmp = (Table1) bt;
    tmp.do_something();
}
else if (bt instanceof Table2) {
    Table2 tmp = (Table2) bt;
    tmp.do_something_else();
}

...

希望这有帮助!

答案 1 :(得分:1)

没有任何内容表明你不能在子类中拥有不同的字段。您遇到的问题是一个常见的设计问题,其中扩展类虽然看似合乎逻辑,但最终会使事情变得更复杂。

从OOP的角度来看,我认为你对BaseTable使用抽象类的方法并不好。作为一般规则,扩展类只有在超类和子类具有“is-a”关系时才有意义。换句话说,当您通过扩展创建的子类实际上是超类的“is-a”版本时。在你的情况下,这是真的。您创建的每个表都是抽象BaseTable的某个版本。

扩展的问题,我确信你意识到这一点,是超类或子类中的更改不会在其他相关实例中进行。 BaseTable类中的更改不会反映在您创建的子类中。当你处理3个表时,这并不是什么大问题。如果您的数据库有40个表,这可能会变得非常痛苦。

话虽这么说,抽象类方法确实是你最好的选择。使用接口是不正确的,因为它会为所有表分配一个类型,即所有表都被视为BaseTable,没有类层次结构。最终结果可能会以相同的方式工作,但这很奇怪而且令人困惑,不应该这样做,因为它会使您的代码更难以遵循。

HashMap问题相对容易处理。如果要将3个表中的每个表存储在自定义集合中,则可以使用3个单独的类来使用heterogeneous container。这样,您可以存储Table1,Table2和Table3的实例,而不必将所有内容都包含在BaseTable中,然后再使用instanceof。