c#对基类继承感到困惑

问题描述 投票:0回答:2

关于类如何从彼此继承方法,我感到很困惑。我已经理解了基类的继承,然而,我不明白一个例子中的某些代码。它涉及搜索二叉树,我找不到任何更好地解释代码如何继承的资源。

我的目的是了解它,以便我可以使用它来搜索链表。

如果有人可以参考我解释这一特定领域的任何相关文献,我将不胜感激。

我突出了代码部分,我还没有真正理解它是如何被修复的。特定部分首先发布:

public Company Read(string bezeichnung)
{
    return stri.Search(new Company() { Bezeichnung = bezeichnung });
}

整个计划:

using System;
using System.IO;
using System.Text;
using System.Net;

namespace CompanySearch
{
    class Program
    {
        static void Main(string[] args)
        {
            StreamReader r = new StreamReader(@"C:\Users\chris\Desktop\algo\fuckit\unternehmen.csv", Encoding.Default);
            Companies stri2 = new Companies(r);
            while (true)
            {
                Console.Write("Unternehmensbezeichnung eingeben: ");
                string name = Console.ReadLine();
                if (string.IsNullOrEmpty(name))
                    break;
                //Company konk = stri2.Read(name);
                Company konk = new Company();
                konk = stri2.Read(name);
                if (konk == null)
                    Console.WriteLine("Unternehmen nicht gefunden!");
                else
                    Console.WriteLine(konk + "\n");
            }
        }
    }

    public class Companies
    {
        private BinaryTree<Company> stri = new BinaryTree<Company>();
        public Companies(StreamReader rp)
        {
            // Spaltenüberschriften auslesen
            //var tokens = rp.ReadLine().Split(new char[] { ';' });
            //if (tokens.Length != 3)
            //    throw new ArgumentException("More than 3 columns in company file");
            string line;
            while ((line = rp.ReadLine()) != null)
            {
                var tokens = line.Split(new char[]{';'});
                //tokens = line.Split(new char[] { ';' });
                stri.Add(new Company()
                {Bezeichnung = tokens[0], Branche = tokens[1], Ort = tokens[2]});
            }

            rp.Close();
        }

        public Company Read(string bezeichnung)
        {
            return stri.Search(new Company()
            {Bezeichnung = bezeichnung});
        }
    }

    public class Company : IComparable<Company>
    {
        public string Bezeichnung
        {
            get;
            set;
        }

        public string Branche
        {
            get;
            set;
        }

        public string Ort
        {
            get;
            set;
        }

        public int CompareTo(Company other)
        {
            return Bezeichnung.CompareTo(other.Bezeichnung);
        }

        public override string ToString()
        {
            return string.Format("Bezeichnung: {0}\tBranche: {1}\tOrt: {2}", Bezeichnung, Branche, Ort);
        }
    }

    public enum TraverseModeEnum
    {
        PreOrder,
        PostOrder,
        InOrder,
        ReverseInOrder
    }

    public class BinaryTree<T>
        where T : IComparable<T>
    {
        private sealed class Node<TNode>
            where TNode : IComparable<TNode> // TNode muss IComparable implementieren
        {
            public TNode Item
            {
                get;
                set;
            }

            public Node<TNode> Left
            {
                get;
                set;
            }

            public Node<TNode> Right
            {
                get;
                set;
            }

            public int CompareTo(TNode other)
            {
                return Item.CompareTo(other);
            }
        }

        private Node<T> root;
        public int Count
        {
            get;
            private set;
        }

        public TraverseModeEnum TraverseMode
        {
            get;
            set;
        }

        public BinaryTree()
        {
            TraverseMode = TraverseModeEnum.PreOrder;
        }

        public void Add(T item)
        {
            if (root == null)
                root = new Node<T>()
                {Item = item};
            else
                addTo(root, item);
            Count++;
        }

        public void AddRange(T[] items)
        {
            foreach (var item in items)
                Add(item);
        }

        private void addTo(Node<T> node, T item)
        {
            if (item.CompareTo(node.Item) < 0)
            {
                if (node.Left == null)
                    node.Left = new Node<T>()
                    {Item = item};
                else
                    addTo(node.Left, item);
            }
            else
            {
                if (node.Right == null)
                    node.Right = new Node<T>()
                    {Item = item};
                else
                    addTo(node.Right, item);
            }
        }

        public bool Contains(T item)
        {
            Node<T> node = root;
            while (node != null)
            {
                int c = node.Item.CompareTo(item);
                if (c == 0)
                    return true;
                if (c > 0)
                    node = node.Left;
                else
                    node = node.Right;
            }

            return false;
        }

        public T Search(T item)
        {
            Node<T> node = root;
            while (node != null)
            {
                int c = node.Item.CompareTo(item);
                if (c == 0)
                    return node.Item;
                if (c > 0)
                    node = node.Left;
                else
                    node = node.Right;
            }

            return default (T);
        }

        public void Clear()
        {
            root = null;
            Count = 0;
        }

        public override string ToString()
        {
            string s = "";
            int level = 0;
            traverse(root, level, ref s);
            return s;
        }

        private void traverse(Node<T> node, int level, ref string s)
        {
            if (node == null)
                return;
            bool reverse = TraverseMode == TraverseModeEnum.ReverseInOrder;
            if (TraverseMode == TraverseModeEnum.PreOrder)
                s += "".PadLeft(level, ' ') + node.Item.ToString() + "\n";
            traverse(reverse ? node.Right : node.Left, level + 2, ref s);
            if (TraverseMode == TraverseModeEnum.InOrder || TraverseMode == TraverseModeEnum.ReverseInOrder)
                s += "".PadLeft(level, ' ') + node.Item.ToString() + "\n";
            traverse(reverse ? node.Left : node.Right, level + 2, ref s);
            if (TraverseMode == TraverseModeEnum.PostOrder)
                s += "".PadLeft(level, ' ') + node.Item.ToString() + "\n";
        }
    }
}
c# binary-tree multiple-inheritance
2个回答
1
投票

代码中的BinaryTree<T>类要求T必须实现IComparable<T>。很多list-ish类都提出了类似的要求。如果类型实现IComparable<T>,则意味着可以使用ComparetTo( T t1, T t2 )方法将类的两个实例相互比较。此方法返回T大于,小于或等于另一个的指示。认识到大于,小于或等于完全取决于实现接口的类型。它主要用于基于比较对树,列表或其他结构中的事物进行排序或以其他方式定位。

实现接口看起来像类继承。语法是相同的...但它更像是一个契约,因为一个接口没有代码可以继承。如果你创建一个类似于的类:

class MyClass: IComparable<MyClass>
{
  //--> stuff
}

...那么你有义务使用签名公开可见的方法:

int CompareTo( MyClass a, MyClass b )
{
   //--> look at the two instances and make a determination...
}

该方法可以使用该类的任何特征来确定使a大于,小于或等于b的原因......从而控制它将如何被放置到结构中。

一个类只能从一个其他类继承...但它可以实现所需的多个接口。我猜,这就是多重​​继承。


1
投票

一个。您的代码中没有真正的继承。只执行标准接口,IComparable<T>。实现接口有时称为继承,但它不一样。在这种情况下,它迫使Company实施CompareTo()方法。

湾您有问题的代码只是创建一个临时对象。您可以将其重写为可能更容易理解的内容:

//return stri.Search(new Company() { Bezeichnung = bezeichnung });
var tempCompany = new Company() { Bezeichnung = bezeichnung };
return stri.Search(tempCompany);
© www.soinside.com 2019 - 2024. All rights reserved.