Java关于实现方法中运行时类型检查的问题

标签 java oop design-patterns

我正在设计一些java对象来表示图形和树。对于我的用例,我将使用这两种数据类型,但我也希望我的图形算法能够在我的树上工作。

import java.util.List;

public interface Node<T> {
    T getValue();
    List<? extends Node<T>> getNeighbors();
    void addNodes(List<? extends Node<T>> nodes);
}

public interface TreeNode<T> extends Node<T> {
    List<? extends TreeNode<T>> getChildren();
    void addChildren(List<? extends TreeNode<T>> treeNodes);

    @Override
    default List<? extends Node<T>> getNeighbors() {
        return getChildren();
    }

    @Override
    default void addNodes(List<? extends Node<T>> nodes) {
        if(nodes.getClass().isInstance(getChildren().getClass())) {
            addChildren((List<? extends TreeNode<T>>) nodes);
        } else {
            throw new RuntimeException("Type error!");
        }
    }
}

我的问题是关于如何处理 TreeNode 接口(interface)中 Node 接口(interface)中的 addNodes 方法。 addNodes 方法必须位于 Node 接口(interface)中,因为我希望允许人们编写可以将节点添加到图中的代码。但是,我也不希望人们向树节点添加任意节点(例如向树节点添加图形节点)。

为了防止这种情况,我在运行时检查节点的类型,如果类型不正确则抛出异常。我只是想知道这是否是完成我想要的事情的最佳方式或者是否有更好的做法?

感谢您的帮助:)

最佳答案

如果我理解正确的话,你想要的是所谓的 curiously recurring template pattern (的变体) 。 Node 类型不仅需要通过其有效负载类型 (T) 进行参数化,还需要通过其可使用的节点类型进行参数化。所以你想要这样的东西:

public interface Node<T, N extends Node<T, N>> {
    T getValue();
    List<N> getNeighbors();
    void addNodes(List<N> nodes);
}

public interface TreeNode<T> extends Node<T, TreeNode<T>> {
    List<TreeNode<T>> getChildren();
    void addChildren(List<TreeNode<T>> treeNodes);

    @Override
    default List<TreeNode<T>> getNeighbors() {
        return getChildren();
    }

    @Override
    default void addNodes(List<TreeNode<T>> nodes) {
        addChildren(nodes);
    }
}

演示(仅显示编译):https://ideone.com/44qrmX

关于Java关于实现方法中运行时类型检查的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53797703/

相关文章:

java - 如何判断线程是否已完成?

c++ - 上下文中的错误

php - 在 PHP 中的类初始化时传递可选配置变量

c# - 模拟 System.Web.Caching.Cache - 模拟或检查 null?

c++ - 在多线程中添加到 vector

java - 如何在 Android 操作系统中通过 Java 访问设备驱动程序?

java - lwjgl isKeyDown 取消其他键

oop - 单一职责原则与贫血领域模型反模式

design-patterns - 责任链设计模式与使用简单的if-elseif-else block 有什么区别?

java - 简单的主动 mq java 发送到由 stomp javascript 创建的主题