1

我正在 C# 中创建一个二叉搜索树类。我通过从二叉树类派生来创建该类,因为二叉搜索树是一种二叉树。所以我将在二叉树类中拥有大部分常用方法,并在二叉搜索树中共享它们。

现在:BinaryTree 类有两个方法“AddToLeft”和“AddToRight”方法,这两个方法必须能够在这个类之外访问,即在Main 方法中向二叉树添加节点。所以我把它们公开了。并且这两种方法也应该可以在二叉搜索树类(重用)中访问,以根据条件将节点添加到二叉搜索树。

但是现在由于 Insert 方法是二叉搜索树将节点插入 BST 的候选方法,但 AddToLeft 和 AddToRight 不是。所以这两种方法不应该暴露给我在 BST 对象上的二叉搜索树的客户端(外部世界)。如何设计这个类。?

我试过了:

  1. 将这两种方法密封在二叉树类中,它没有帮助。
  2. 在 base 中声明它们是 public 并在派生中声明它们。这也没有帮助,因为 public 不能在派生类中被继承为 protected。

请帮助设计课程。

public class BTNode
{
    public int data;
    public BTNode Left { get; set; }
    public BTNode Right { get; set; }
    public BTNode(int data)
    {
        this.data = data;
    }
}

public class BinaryTree
{
    public BTNode Root { get; set;}
    public BinaryTree() : this(null) { }
    public BinaryTree(BTNode node) { Root = node; }
    // this method common for its derived class too
    public void AddToLeft(BTNode current, BTNode node) 
    {
        current.Left = node;
    }

    // this method common for its derived class too
    public void AddToRight(BTNode current, BTNode node)
    {
        current.Right = node;
    }
}

public class BinarySearchTree : BinaryTree
{       
    public BinarySearchTree(int val)
    {
        Root = new BTNode(val);    
    }
    public void Insert(int val)
    {
        BTNode node = new BTNode(val);

        if (Root.data >= val)
            base.AddToLeft(Root, node); // I should be able to call this method here
        else
            base.AddToRight(Root, node); // I should be able to call this method here
    }
}

class Program
{
    static void Main(string[] args)
    {
        BinaryTree bt = new BinaryTree();
        BTNode root = new BTNode(3);
        BTNode node1 = new BTNode(4);
        BTNode node2 = new BTNode(7);

        bt.AddToLeft(root,node1); // i should be able to access this method here.
        bt.AddToLeft(root, node2); // i should be able to access this method here.

        BinarySearchTree bst = new BinarySearchTree(6);
        bst.Insert(4);
        bst.Insert(8);

        // This is the problem.
        // these two methods should not be visible on the bst object.
        // insertion to bst is done only through insert() method
        // but these two methods should be accessible inside the binarysearchtree class
        // to add the nodes.
        bst.AddToLeft(root,node1); // i should not access this method here on this object
        bst.AddToRight(root, node2); // i should not access this method here on this object
    }
}
4

3 回答 3

2

您在键入代码时尝试做的事情是矛盾的。您是说您的班级BinaryTreeBinaryTree.

我可能会做的不是派生自BinaryTree,而是拥有一个私有字段,该字段BinaryTree在您的BinarySearchTree类中保存 a 并公开您希望通过公共访问器公开的功能BinaryTree(因此BinarySearchTree不再是二叉树的一种类型,但仍然可以访问通过使用 a 的实例初始化的私有字段实现功能BinaryTree。)

我当然可以理解做BinarySearchTree一个类型的吸引力BinaryTree,但是你要么放弃这两种方法的封装,要么放弃基类型的分类。当您不提供与它相同的外部 API 时,您不能声称满足基本类型分类的要求。

如果您真的希望能够尝试像上面那样做事情,您可以覆盖您不希望客户使用的方法并InvalidOperationException从这些方法中抛出 s。但这不是很优雅,因为它在编译时对您没有帮助,只会在运行时抱怨,这不是谨慎的设计。

于 2012-12-25T08:20:17.100 回答
0

尝试使用 AddToLeft 和 AddToRight 方法的 private 关键字而不是 public。因为私有方法只对基类可见。

谢谢

于 2012-12-25T11:05:24.337 回答
0

更多关于矛盾 - 这是一个形而上学问题:如果 BinaryTree 的定义是它必须能够执行左右加法,则 BinarySearchTree 不是 BinaryTree。如您所知,二叉树是一种结构,每个节点都有两个子节点。BinarySearchTree 不是 BinaryTree,而是使用BinaryTree 进行内部存储的基于键的排序列表。

第一个是结构,第二个是更高级别的结构,具有特定的内部存储结构和算法。BinarySearchTree 可能是 Dictionary 的最佳子类,其中 KeyType 是索引类型,ValueType 是存储在每个节点(可能是一个集合)的类型。您希望能够将带有键的元素添加到集合中,并稍后通过该键将它们拉回,并具有一些额外的好处(可能是排序遍历等)。那是一个字典扩展,而不是 BinaryTree 扩展,所以你将它包装起来的方法是要走的路,我会实现 IDictionary。

于 2013-01-20T16:56:28.750 回答