Java 最好是扩展类还是直接修改它?

Java 最好是扩展类还是直接修改它?,java,class,extend,Java,Class,Extend,因此,我正在为Java中的数据结构创建可视化。我已经有了数据结构(二进制搜索树)的实现,但是我需要向包含的节点类添加一些附加功能。就约定和最佳实践而言,我应该创建一个具有此附加功能的节点子类,还是应该修改现有内容并将其记录在其中 我的问题和别人的问题很相似,但有点过头了 我知道这对我所做的事情可能没有多大关系,所以我把这个问题作为一个一般性的问题来问 编辑:我可能应该说得更清楚些。除了添加两个额外字段(x和y坐标加上一个布尔值以设置该节点是否高亮显示)和访问/修改这些字段的函数之外,我的修改实际

因此,我正在为Java中的数据结构创建可视化。我已经有了数据结构(二进制搜索树)的实现,但是我需要向包含的节点类添加一些附加功能。就约定和最佳实践而言,我应该创建一个具有此附加功能的节点子类,还是应该修改现有内容并将其记录在其中

我的问题和别人的问题很相似,但有点过头了

我知道这对我所做的事情可能没有多大关系,所以我把这个问题作为一个一般性的问题来问

编辑:我可能应该说得更清楚些。除了添加两个额外字段(x和y坐标加上一个布尔值以设置该节点是否高亮显示)和访问/修改这些字段的函数之外,我的修改实际上并没有改变原始实现。我正在使用的节点类也包含在BST实现中

从你的答案来看,这两种情况似乎都有争议。我同意,一般来说,创建一个单独的类或接口可能是最好的做法。创建另一个类似乎很棘手,因为您仍然需要一种从节点中提取数据的方法。我使用的BST实现是通用的,并且在Node类或BST类中没有任何这样的功能来返回数据,所以至少我必须添加它


感谢您提供的信息性回复。

我想说的是,在向现有实现添加功能的一般情况下,您应该扩展现有实现,而不是修改它

这是我的理由。如果该节点是在二进制搜索树实现之外的任何地方使用的,那么当您修改它时,您需要找到它使用的所有地方,以确保这些地方都不会与您的修改相冲突。虽然仅仅以新方法的形式添加功能通常不会导致问题,但它可能会导致问题。你永远不知道一个物体是如何使用的

第二,即使它只在二元搜索树中使用,您仍然需要确保BST的实现在您的修改中发挥良好的作用


最后,如果你扩展它,你不必担心第一点和第二点。而且,您还可以获得额外的好处,使您的修改始终与原始实现分开。这将更容易跟踪您所做的事情并对其进行评论。

要回答的问题是,“基本功能”在您不可视化数据结构的情况下是否有用,甚至是不受欢迎的

您甚至可能根本不想扩展该类。在我看来,没有更多细节,您的数据结构似乎可以正常工作。您可以创建一个知道如何将其可视化的新类


也就是说,不是一个知道如何可视化自身的数据结构,而是一个数据结构和另一个知道如何可视化数据结构的类。见鬼-你可能会发现这会演变成另一个完整的类层次结构,因为你可能需要可视化队列、堆栈等。这与你的二元搜索树无关。

因为你一般都会问,所以这里有一个简短的答案:这取决于具体情况

首先,假设子类与其父类具有“IS-A”关系。如果您不能说您的新子类是原始类的一种特定类型,那么您提出的问题是错误的,应该创建一个新的、不相关的类

  • 如果新代码与类的核心目的密切相关,并且适用于类的所有成员(例如,所有BST),则最好修改。高是好的
  • 如果您的新代码与类的核心用途相关,但仅与该类型的某些对象相关(例如,仅与平衡的BST相关),那么子类化可能是一种方法
  • 根据您正在更改的内容、使用代码的位置、使用代码的人员/组织等,您的更改可能会导致其他代码出现意外行为,因此在修改现有代码之前,您应该三思而后行。这并不意味着自动对常用的东西进行子类化;出于上述原因,这通常是错误的

在您的具体情况下,我同意n8wrl;由于可视化与数据结构无关,因此实现一个完整的独立的
可视化接口可能比创建一个
DrawableBSTNode
子类要好。

混淆逻辑上独立的功能将导致混乱。子类化是一种非常特殊的关系,经常被过度使用。子类化适用于is-a-Kind关系


如果您想可视化某些东西,为什么不为此创建一个完全独立的类呢?您只需将节点对象传递给该节点即可。(或者更好的是,使用一个界面。)

没有简单的答案,知道何时以及如何添加功能是一件需要长期学习的事情

仅仅添加到基类似乎是一个简单的解决方案,但它会污染基类。如果这是一个类,您可以合理地期望另一个程序(甚至是您程序的一部分)使用,那么您添加的功能在您的类的责任上下文中是否有意义?如果不这样做,这可能是一个糟糕的举动。您是否正在添加将基类链接到特定用途的依赖项?因为如果你是这样的话,那就是把代码重用抛到了窗外

继承是许多工程师所热衷的解决方案,也是一条诱人的路线。但随着我作为一名工程师的成长,我很少使用它。继承只应用于真正的is-a关系,您需要尊重 否则你以后会后悔的。由于Java只允许单一继承,这意味着您只需一次尝试子类型
public interface HasNode {
    public Node getNode();
}