java - 在这种情况下,我选择组合而不是继承是正确的吗?

标签 java oop inheritance data-structures

我正在编写二叉树作为学习练习的一部分。我试图适应删除二叉树中节点的两种方法:DeleteByMerge 和DeleteByCopy。

为用户提供在这些方法之间进行选择的最佳方式是什么?

我倾向于组合方法(如策略):

public class BinaryTree{

   BtreeDelete del;
   public BinaryTree(){
      this.del = new DeleteByCopy();
   }

   public BinaryTree(BtreeDelete del){
      this.del = del;
   }

   public boolean delete(Node node){
       // Common code
       del.delete()
   }

}

类DeleteByMerge 和DeleteByCopy 实现了接口(interface)BtreeDelete,因此我可以在实例化期间进行连接,如下所示:

BinaryTree btree = new BinaryTree(new DeleteByMerge());

或者

BinaryTree btree = new BinaryTree(new DeleteByCopy());

.

基于继承的方法:

public class BinaryTree{

   public BinaryTree(){

   }

   public boolean delete(Node node){
       // Common code
       deleteNode();
   }

   // An overriddable hook with a default implementation
   protected boolean deleteNode(Node node){
        //By default implementation for DeleteByCopy is provided
   }

}

删除的不同实现将需要单独的子类(导致可能的类爆炸):

public class BtreeDelByMerge extends BinaryTree{

   protected boolean deleteNode(Node node){
       // Code for deleting a node by Merging
   }
}

我对继承方法的疑虑是 BtreeDelByMerge 不是 Btree 的一种类型,它的行为不会发生太大变化,并且只为其其中一个方法创建一个单独的子类似乎不自然。此外,如果我想要一棵具有插入和删除等特定实现的树,它也不会像组合方法那样。

在这种情况下,采用继承方式有什么特别的优点吗?另外,提供选择是个好主意吗?例如:集合框架没有提供太多选择,因此实现封装得很好,并且一致但严格。

最佳答案

我认为这取决于deleteNode的实现。如果它所做的只是在节点本身上工作,那么您的第一种方法(策略方法)看起来干净而优雅。

如果存在(或者将来可能存在的情况)通过使用类的 protected 成员/方法可以更有效地进行删除,我会选择继承方法。

例如:假设您有一个内部 HashMap ,可以帮助您更快地遍历树,然后只向左/右/父方向行走,并且您使该映射受到保护。现在,如果您选择策略方法,您将无法使用该 map ,并且可能需要它来更快地删除。如果您选择继承方法并使 map 受到保护,您也许能够改进简单的删除算法。

此外,这只是一个练习,但如果您在“现实生活”场景中面临这种困境,您需要记住,决定使用 API 是一种 promise 。您应该考虑我提到的几点。

  1. 制定策略 - 让其他人更容易注入(inject)行为。
  2. 继承 - 更易于使用类内部实现。

关于java - 在这种情况下,我选择组合而不是继承是正确的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19509627/

相关文章:

java - 如何解决任务 ':app:mergeDebugResources' 执行失败的问题。在 Android Studio 3.6.2 中

Java:无法访问对象的元素

c++ - 为什么 friend 类成员可以通过公共(public)继承类的对象访问它成为 friend 的类的私有(private)成员?

c# - 无法访问我的对象的成员

objective-c - objective-c - 制作一个 NSManagedObject 和从同一父类继承的常规 NSObject 类

带有 knockout.js 函数覆盖的 Javascript

javascript - java 8 Nashorn 引擎无法比较日期

java - 如何编写自定义 JPanel(又名 View )的 Android 等效项

java - Databricks Spark 笔记本在运行之间重复使用 Scala 对象?

c++ - 私有(private)继承与公开迭代器