【问题标题】:Java Generic Interface method-overloadJava通用接口方法-重载
【发布时间】:2018-02-24 17:48:59
【问题描述】:

我正在尝试为我在大学的任务表制作一个界面。我必须为各种数据结构实现所有这些方法,所以我想实现这个接口。

问题是,数据结构必须是通用的,例如:LinearList<T>,其中键的类型是 T。现在不同的数据结构具有不同的元素,例如。 LinearList<T> 具有 ListItem<T> 作为元素,而 Trees 具有 TreeNode<T>

所以我想我用 <C, T> 创建一个接口,其中 C = ListItem 和 T 类型 ex。整数。

现在我有一些重载的方法,例如:

insert(T key)
insert(ListItem<T> item)

所以用户可以添加一个键或者他可以添加例如另一个列表的头部。但是现在我遇到了一个我不明白的编译器错误:

java:15: error: name clash: insert(T,int) and insert(C,int) have the same erasure
    boolean insert(T key, int pos);

我可以做些什么来启用我上面解释的重载方式?因为在一个抽象类中我尝试过它并且它有效。

编辑: 好的,就像在讨论的 cmets 中一样,我现在使用不同的方法名称。它似乎是其他集合用来解决问题的解决方案,并且如上所述隐藏(?)更多实现细节。非常感谢您的支持!

package interfaces;

/**
 * Interface with all methods for the data-structs I have to learn for the exam
 *
 * <C> is the class of the Elements to be entered ex: ListItem<T>
 * <T> the type of the elements stored in the data-structs
 * 
 * @author 
 */
public interface ExamPreparation<C, T> {

    boolean insert(C item, int pos);

    boolean insert(T key, int pos);

    boolean insertAtHead(C item);

    boolean insertAtHead(T key);

    boolean insertAtTail(C item);

    boolean insertAtTail(T key);

    boolean insertSorted(C item, Comparator<T> comp);

    boolean insertSorted(T key, Comparator<T> comp);


    // ========== Remove Methods ==========

    boolean remove(T key);

    boolean removeAll(T key);


    // ========== Overwrite Methods ==========

    /**
     * takes the first appearance of oldKey and overwrites it wit
    h newKey
     *
     * @param newKey
     * @param oldKey
     * @return true if overwrited. False if oldKey is not in list
     */
    boolean overwrite(T newKey, T oldKey);

    /**
     * takes all the oldKeys and overwrites it with the newKey
     *
     * @param newKey
     * @param oldKey
     * @return returns true if at least one oldkey was found
     */
    boolean overwriteAll(T newKey, T oldKey);

    /**
     * overwrite at position
     *
     * @param newKey
     * @param pos
     * @return returns false if pos is not valid else true
     */
    boolean overwriteAt(T newKey, int pos);


    // ========== Other ==========

    boolean contains(T key); 
}

【问题讨论】:

  • 删除C,只使用T,正如你已经解释过的insert(T)insert(ListElement&lt;T&gt;)完全没问题,不会冲突。
  • 为什么我作为用户想知道其他列表的头部?看看 Java 的 Collection API 实现——LinkedList 只是一个List。不要在公共 API 中公开内部实现细节。
  • 只需将插入列表中所有元素的方法命名为不同的名称,例如insertAll(ListItem&lt;T&gt;)。这就是标准集合的作用。
  • Java 集合有addAll(Collection,它采用另一个集合并添加所有项目。您的列表可以确定用户想要添加另一个列表并在内部请求头部。再次隐藏实现细节
  • 正如其他人指出的那样:您应该考虑是否应该有插入“项目”和“键”的选项根本。 Buf if 你想要两个选项:为什么不相应地命名方法呢? insertIteminsertKey 左右。请明确点。看看List 接口引起的头痛,有remove(T t)remove(int index)。对于List&lt;Integer&gt; 的情况,这会导致非常 微妙的错误。将方法命名为 removeElementremoveByIndex 可以避免很多问题......

标签: java generics overloading


【解决方案1】:

声明一个新接口怎么样

interface ElementType<T> {

}

然后制作可能的元素类型;像这样扩展或实现ElememtType

interface ListItem<T> extends ElementType<T> {

}

interface TreeNode<T> extends ElementType<T> {

}

最后更改ExamPreparation 的声明 来自

public interface ExamPreparation<C,  T>

public interface ExamPreparation<C extends ElementType<T>,  T>

这样下面的代码编译就没有问题了;

    ListItem<String> item = null;
    ExamPreparation<ListItem<String>, String> examPreparation = null;
    boolean isInserted;
    isInserted = examPreparation.insert("12", 0);
    isInserted = examPreparation.insert(item, 0);

【讨论】:

  • C extends Collection&lt;T&gt;?鉴于 OP 所描述的内容,为什么会有帮助?
  • 只声明CT 没有任何关系将使这个接口违反可以和不能称为元素的内容。像T 是什么元素?所以这样的声明就清楚了
  • @BoristheSpider 你是对的,我错了。编辑后的帖子怎么样?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-26
  • 2014-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-28
相关资源
最近更新 更多