我想为不同的数据结构编写一些不同的算法(例如树,列表,数组,...)。除了方法参数外,数据结构的方法相同90%。
public class BinaryTreeNode<T> {
public T key;
public BinaryTreeNode<T> leftChild;
public BinaryTreeNode<T> rightChild;
public boolean find(BinaryTreeNode<T> root, T key) { /* implementation */ }
}
public class ListItem<T> {
public T key;
public ListItem<T> next;
public boolean find(ListItem<T> root, T key) { /* implementation */ }
}
为了不必单独编写每个方法,我做了一个抽象的DataStruct<T>
类
public abstract class DataStruct<T> {
/**
* finds the key in dataStruct
* @param dataStruct DataStruct to look for key
* @param key value of type T to find in dataStruct
* @return true if key is in dataStruct else false
*/
public abstract find(DataStruct<T> dataStruct, T key);
}
我让BinaryTreeNode<T>
和ListItem<T>
extend
DataStruct<T>
现在我的问题是访问类属性。我这样解决了:
public class ListItem<T> extends DataStruct<T> {
public T key;
public ListItem<T> next;
@Override
public boolean find(DataStruct<T> listItem, T key) {
ListItem<T> tmpListItem = (ListItem<T>) listItem;
while(tmpListItem.next != null) {
if(tmpListItem.key == key)
return true;
}
}
}
但是它感觉不太适合编码,因为我必须创建一个临时ListItem<T>
才能施放DataStruct<T>
才能访问ListItem<T>
的类属性。
有更好的方法吗?
由于find
方法不是static
方法,因此它接受DataStruct<T>
对象并在该对象上执行搜索是没有意义的。进行搜索本身更有意义,这消除了施放任何东西的需要:
public boolean find(T key) {
ListItem<T> tmpListItem = this;
while(tmpListItem.next != null) {
if(tmpListItem.key.equals(key))
return true;
tmpListItem = tmpListItem.next;
}
}
现在,您的某些方法确实需要DataStruct<T>
参数,例如,您需要在ListItem
ACCPET中实现这些方法,仅ListItem
,检查输入参数的类型,投掷是有意义的如果跑步型错误并执行演员表,则例外(或返回false,或任何有意义的事物)。这是equals
等方法中的常见实践,该方法接受Object
,通常要求运行时类型为特定类型。
例如:
public boolean find(DataStruct<T> listItem, T key) {
if (!(listItem instanceof ListItem)) {
// decide whether to return false or throw an exception
}
ListItem<T> tmpListItem = (ListItem<T>) listItem;
...
}