Java 容器对象中的泛型getter
一些容器类保存基类“Table”(如WoodenTable、MetalTable…)的对象列表。每个表类保留其MaterialType(MaterialType.Wood、MaterialType.Metal…)。问题是如何为可以返回表的每个子类的容器类提供适当的getter方法 到目前为止,我发现了以下方法: 1.以材料类型为参数的吸气剂。如果T类型与materialType不对应,则此处的危险为ClassCastException:Java 容器对象中的泛型getter,java,oop,Java,Oop,一些容器类保存基类“Table”(如WoodenTable、MetalTable…)的对象列表。每个表类保留其MaterialType(MaterialType.Wood、MaterialType.Metal…)。问题是如何为可以返回表的每个子类的容器类提供适当的getter方法 到目前为止,我发现了以下方法: 1.以材料类型为参数的吸气剂。如果T类型与materialType不对应,则此处的危险为ClassCastException: <T extends Table> T get
<T extends Table> T getTable(MaterialType materialtype)
WoodenTable table = getTable(MaterialType.Wood);
MetalTable table = getTable(MaterialType.Wood); // ups... exception
4.仅用于表接口的Getter。如有必要,在容器类之外进行强制转换
Table getTable(MaterialType materialType)
WoodenTable woodenTable = (WoodenTable)getTable(MaterialType.Wood)
还有其他(更好的)方法吗?如果不是,那么哪一个最合适或者最不难闻?应该是这么简单:
public Table getTable()
{
return this.table;
}
这将返回一个表
对象,调用方可以根据自己的需要处理它。类似于下面的块:
public Collection<String> getCollection()
{
return new ArrayList<String>();
}
以及以下代码:
public static void main(String[] args)
{
Collection<Table> tables = new ArrayList<Table>();
tables.add(new WoodenTable());
tables.add(new MetalTable());
for(Table table : tables)
{
table.doSpecial();
}
}
publicstaticvoidmain(字符串[]args)
{
集合表=新的ArrayList();
tables.add(新的WoodenTable());
tables.add(新MetalTable());
用于(表:表)
{
表.doSpecial();
}
}
这里的方法是有一个共享的公共API。并且每个类的内部都没有公开,因此为每个类做一些特殊的事情的需要隐藏在公共接口后面。这就避免了必须执行检查实例或任何其他混乱的方法来解决这类问题。我建议不要将表视为具有属性(材质)的数据结构,而是开始将它们视为“人”()。不要从他们身上得到“材料”。相反,让他们暴露自己的行为
更改表的设计时,将自动更改其容器的设计。很明显,容器不应该关心表的材质,而应该让它们控制它们是想离开容器还是留在容器中。不要将按枚举键入与按子类键入混为一谈。挑一个,坚持下去。我怎样才能避免呢?考虑到下面的Woot4Moo响应,我需要类似选项4的东西。我可以完全避免枚举的唯一方法是使用选项3(不是很吸引人)。容器集合是同质的(始终包含相同的基类型)还是异质的(包含不同的基类型)?我将研究Typesafe异构容器模式,并了解如何扩展它以获得对象列表,而不是一个单一的对象@ewernli是的,这与我到目前为止使用的选项2非常相似。谢谢,很高兴知道这东西有个名字!我在这里的问题是,我经常需要处理接口未提供的子类特有的函数。这意味着需要以某种方式指定我希望从容器类中获取哪个子类(以避免“instanceof”)。@CzujnyJakZuraw对,我理解这个问题。在上面的集合示例中,它的解析如下:
setstrings=newhashset(getCollection())代码>。在您的用例中,您可以这样做:TableSubA=newtablesuba(getTable())代码>要么你没有领会我的意思,要么是我不明白这里的某些内容:)。也许我应该强调,我的TableContainer对象包含许多不同类型的表。在这种情况下,如何在不指定任何类型参数的情况下从中检索所有木制表格?@CzujnyJakZuraw确保TableContainer包含许多不同的表格类型。为了确认您想要执行以下操作:for(Table t:TableContainer){t.doSomething();}
正确吗?或者我遗漏了什么案例?是的,这可能是一个用例,但通常我还需要这样的东西:for(Table t:TableContainer){(subassa)t.dosomethingsspecificfora();},这就是我的问题开始的地方。
public Collection<String> getCollection()
{
return new ArrayList<String>();
}
public interface Table
{
Table getTable();
void doSpecial();
}
public class WoddenTable implements Table
{
...
public Table getTable()
{
return this;
}
public void doSpecial()
{
mySpecial();
}
private void mySpecial()
{
System.out.println("Wooden");
}
}
public class MetalTable implements Table
{
...
public Table getTable()
{
return this;
}
public void doSpecial()
{
mySpecial();
}
private void mySpecial()
{
System.out.println("Metal");
}
}
public static void main(String[] args)
{
Collection<Table> tables = new ArrayList<Table>();
tables.add(new WoodenTable());
tables.add(new MetalTable());
for(Table table : tables)
{
table.doSpecial();
}
}