Расширить класс без изменения базовой реализации алгоритма?

Я пишу дерево интервалов в C#. Что я хотел бы сделать, это просто расширить существующее двоичное дерево поиска для хранения интервалов и не нужно переписывать основные функции (добавлять, получать, удалять).

Внутри BST у меня есть Node учебный класс:

protected class Node 
{
    public KeyValuePair<TKey, TVal> Data;
    public Node Left, Right;

    public Node(KeyValuePair<TKey, TVal> data,
        Node left = null, Node right = null)
    {
        Data = data;
        Left = left; Right = right;
    }
}

И внутри дерева интервалов у меня есть IntervalNode класс, который расширяется Node:

private class IntervalNode : Node
{
    public Interval<TInterval> Interval;
    public override string ToString()
    {
        return string.Format("A={0}, B={1}", Interval.A, Interval.B);
    }

    public IntervalNode(KeyValuePair<TInterval, TVal> data, 
        Node left = null, Node right = null)
        : base(data, left, right)
    {
    }
}

Проблема, с которой я сталкиваюсь, пытается сохранить IntervalNode в дереве, а не Node, Есть ли способ теперь я могу использовать существующие базовые реализации Add с IntervalNode?

protected Node Add(Node root, KeyValuePair<TKey, TVal> data)
{
    // regular binary search tree insert
} 

Я думаю, что я хотел бы иметь возможность сделать что-то вроде этого:

public void Add(Interval<TInterval> intvl, TVal val)
{
    _root = Add((Node)_root, new KeyValuePair<TInterval, TVal>(intvl.A, val));
    IntervalNode inserted = (IntervalNode)Get(_root, intvl.A);
    inserted.Interval = intvl;
}

// tree should store IntervalNodes, not Nodes
private IntervalNode _root;

1 ответ

Решение

Ваш пример кода не скомпилируется, но вот что, я думаю, вы пытаетесь получить:

protected class Node
    {
        public KeyValuePair<TKey, TVal> Data;
        public Node Left, Right;

        public Node(KeyValuePair<TKey, TVal> data,
            Node left = null, Node right = null)
        {
            Data = data;
            Left = left; Right = right;
        }

        public virtual void Add(Node root, KeyValuePair<TKey, TVal> data)
        {
            //Do whatever
        }
    }

Затем в производном классе:

private class IntervalNode: Node
    {
        public Interval<TInterval> Interval;
        public override string ToString()
        {
            return string.Format("A={0}, B={1}", Interval.A, Interval.B);
        }

        public IntervalNode(KeyValuePair<TInterval, TVal> data, 
            Node left = null, Node right = null)
            : base(data, left, right)
        {
        }

        public override void Add(Node root, KeyValuePair<TInterval, TVal> data)
        {
            //Do whatever you need to, then
            base.Add(root, data);
        }
    }

Вам нужно будет решить проблему с дженериками, которая у вас есть, но вы должны увидеть суть.

поскольку IntervalNode это NodeВы можете хранить его в том же месте, что и базовый класс, нет необходимости приводить его в порядок или выделять хранилище. Это хорошая часть о наследовании.

Другие вопросы по тегам