c# 对 base class 继承感到困惑

c# confused about base class inheritance

我很困惑 类 究竟如何相互继承方法。我已经了解从基础 类 继承,但是,示例中的某些代码我不理解。它涉及搜索二叉树,我找不到任何资源可以更好地解释代码是如何继承的。

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

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

我已经突出显示了我还不太了解它是如何继承的代码部分。具体版块先贴:

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";
        }
    }
}

一个。您的代码中没有真正的继承。只执行了一个标准接口,IComparable<T>。实现接口有时称为继承,但两者并不相同。在这种情况下,它强制 Company 实现 CompareTo() 方法。

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

//return stri.Search(new Company() { Bezeichnung = bezeichnung });
var tempCompany = new Company() { Bezeichnung = bezeichnung };
return stri.Search(tempCompany);

代码中的 class BinaryTree<T> 要求 T 必须实现 IComparable<T>。许多列表式 classes 提出了类似的要求。如果一个类型实现了 IComparable<T>,这意味着 class 的两个实例可以使用 ComparetTo( T t1, T t2 ) 方法相互比较。此方法 returns 表明 T 大于、小于或等于 另一个。意识到 大于、小于或等于 完全取决于实现接口的类型。它主要用于根据比较对树、列表或其他结构中的事物进行排序或定位。

实现一个接口看起来像class继承。语法是一样的……但它更像是一个契约,因为接口没有可继承的代码。如果你做一个 class 这样的:

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

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

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

该方法可以使用 class 的任何特征来确定是什么使得 a 大于、小于或等于 b...从而控制如何将其放入结构中。

一个class只能继承另一个class...但它可以根据需要实现任意多个接口。我猜这就是多重​​继承。