2

某些容器类包含基类“Table”的对象列表(如 WoodTable、MetalTable ...)。每个 Table 类都保留其 MaterialType(MaterialType.Wood、MaterialType.Metal...)。问题是如何为可以返回 Table 的每个子类的容器类提供适当的 getter 方法。

到目前为止,我找到了以下方法:

1.以材料类型为参数的Getter。如果 T 的类型不对应于 materialType,这里的危险是 ClassCastException:

<T extends Table> T getTable(MaterialType materialtype)
WoodenTable table = getTable(MaterialType.Wood);
MetalTable table = getTable(MaterialType.Wood); // ups... exception

2.带Class参数的Getter。安全但对用户来说不是很清楚(与作为参数的 MaterialType 相比):

<T extends Table> T getTable(Class<T> tableClass)
WoodenTable table = getTable(WoodenTable.class);

3.每个表子类的Getter。使用繁琐,编写和添加新的表子类:

WoodenTable getWoodenTable()
WoodenTable table = getWoodenTable();

4.Getter for just Table 接口。如有必要,在容器类之外进行强制转换。

Table getTable(MaterialType materialType)
WoodenTable woodenTable = (WoodenTable)getTable(MaterialType.Wood) 

还有其他(更好的)方法吗?如果不是,那么其中哪一个最合适或最不臭?

4

2 回答 2

0

应该就是这么简单:

public Table getTable()  
{  
     return this.table;
}  

这将返回一个Table对象,由调用者来处理他们想要的。类似于以下块:

public Collection<String> getCollection()  
{  
     return new ArrayList<String>();
}  

主体返回 aArrayList但函数实际上返回 a Collection。使用对象之间最常见接口的定义良好的 API 将为您提供同样的灵活性。

编辑

是的,这可能是一个用例,但我通常还需要类似的东西:for(Table t : TableContainer) { (SubClassA)t.doSomethingSpecificForA();} 这就是我的问题的开始。

让我们假设以下接口和实现:

    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();  
        }  
}  

这里的方法是有一个共享的公共 API。并且每个类的内部都没有暴露,因此为每个类做某事的需要special隐藏在公共接口后面。这可以防止必须执行检查实例或任何其他杂乱的方法来解决此类问题。

于 2012-11-14T13:35:46.367 回答
0

我建议不要将表视为具有属性(材料)的数据结构,而应开始将它们视为“人”(对象思维)。不要从他们那里得到“材料”。相反,让他们暴露他们的行为。

当您更改表的设计时,您将自动更改其容器的设计。很明显,容器不应该关心桌子的材料,而应该让他们控制他们是想离开容器还是留在里面。

于 2012-12-31T14:06:08.937 回答