gpt4 book ai didi

java - 涉及实现接口(interface)的实现问题

转载 作者:搜寻专家 更新时间:2023-11-01 02:55:11 25 4
gpt4 key购买 nike

我正在为不同类型的树编写一组集合类。我这样做是作为一种学习练习,我也希望它能成为有用的东西。我真的很想以正确的方式做到这一点,所以我一直在阅读 Effective Java我也一直在研究 Joshua Bloch 通过查看源代码实现集合类的方式。我似乎很清楚正在做什么,但我还有一些事情需要解决。

我有一个 Node<T>界面和一个AbstractNode<T>实现 Node 的类界面。然后我创建了一个 GenericNode<T> (一个节点可以有 0 到 n 个子节点,并且是 n 叉树的一部分)扩展 AbstractNode<T> 的类并实现 Node<T> .这部分很简单。

接下来,我创建了一个 Tree<T>界面和一个AbstractTree<T>实现 Tree<T> 的类界面。之后,我开始写一个 GenericTree<T>扩展 AbstractTree<T> 的类并实现 Tree<T> .这是我开始遇到问题的地方。

就设计而言,GenericTree<T>只能由 GenericTreeNode<T> 类型的节点组成.这包括根。在我的 Tree<T>我的界面:

public interface Tree<T> {

void setRoot(Node<T> root);

Node<T> getRoot();

List<Node<T>> postOrder();

... rest omitted ...
}

并且,AbstractTree<T>实现这个接口(interface):

public abstract class AbstractTree<T> implements Tree<T> {

protected Node<T> root;

protected AbstractTree() {
}

protected AbstractTree(Node<T> root) {
this.root = root;
}

public void setRoot(Node<T> root) {
this.root = root;
}

public Node<T> getRoot() {
return this.root;
}

... rest omitted ...
}

GenericTree<T> ,我可以有:

public GenericTree(Node<T> root) {
super(root);
}

但这意味着您可以使用 Node<T> 的任何子类型创建通用树.您还可以将树的根设置为 Node<T> 的任何子类型.我希望能够将节点的类型限制为它可以表示的树的类型。要解决这个问题,我可以这样做:

public GenericTree(GenericNode<T> root) {
super(root);
}

然而,setRoot仍然接受 Node<T> 类型的参数.这意味着用户仍然可以使用错误类型的根节点创建树。我如何强制执行此约束?我能想到的唯一方法是:

  • 做一个instanceof它将检查限制在运行时。我不太喜欢这个。
  • 删除 setRoot从接口(interface)并让基类实现此方法。这意味着它不是合约的一部分,任何想要制作新型树的人都需要记住实现此方法。

有没有更好的办法?

我的第二个问题是关于 postOrder 的返回类型这是 List<Node<T>> .这意味着如果用户在 GenericTree<T> 上操作对象和调用 postOrder , 他或她收到一个包含 Node<T> 的列表对象。这意味着在遍历(使用 foreach 构造)时,它们将执行显式转换为 GenericNode<T>。如果他们想使用仅在该类中定义的方法。我不喜欢把这种负担加在用户身上。在这种情况下我有什么选择?我只能考虑从接口(interface)中删除该方法并让子类实现此方法,确保它返回 Node<T> 的适当子类型列表。 .然而,这再次将它从合约中删除,任何想要创建一种新型树的人都必须记住实现这个方法。有没有更好的办法?

最佳答案

我认为您是本末倒置。

实现 Tree<T> 的几个具体实例和 Node<T> .只有在那之后分析他们有什么共同的实现,然后才实现你的 Abstract类,如果他们在这一点上仍然有意义的话。

编辑

回答你的第二个问题:

如果简单Node<T>不会在你的 Tree 中削减它接口(interface),那么你别无选择,只能为通用接口(interface)声明第二个参数并在其上设置边界,如下所示

public interface Tree<
T,
TNode extends Node< T >
>
{

void setRoot(TNode root);

TNode getRoot();

List<TNode> postOrder();

... rest omitted ...
}

然后是抽象树

public abstract class AbstractTree<
T,
TNode extends Node< T >
> implements Tree<T, TNode> {

protected TNode root;

protected AbstractTree(TNode root) {
this.root = root;
}

...
}

然后是泛型树

public class GenericTree< T >
extends AbstractTree< T, GenericNode< T > >
{

public GenericTree ( GenericNode< T > root )
{
super( root );
}

@Override
public List< GenericNode< T > > postOrder ( )
{
...
}
...
}

关于java - 涉及实现接口(interface)的实现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2908952/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com