在java中的子类方法中无法访问抽象类对象的属性

时间:2017-10-05 19:01:28

标签: java algorithm abstract-class

我想为不同的数据结构编写一些不同的算法(例如树,列表,数组......)。除方法参数外,数据结构的方法是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>的类属性。

有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

由于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中实现这些方法只能实现ListItem,它会有意义的是检查输入参数的类型,如果run-type错误则抛出异常(或返回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;
    ...
}