簡體   English   中英

接口和標頭

[英]Interfaces and Headers

今天我遇到了C#接口的概念,我有一個希望很簡單的問題,看看我是否理解它們......它們是否與C ++頭文件非常相似? 我的意思是,從我得到的,你定義一個類的主干,而不是實際定義它的作用,這類似於標題,是正確的嗎? 我閱讀了整個MSDN定義,並沒有真正讓我100%清楚。 我相信我有這個想法(編寫並附上了一個非常基本的程序,看看我是否理解)但是至少在明天晚上至少完全理解它們的基礎知識是非常重要的。

例:

namespace InterfaceTest
{
    class Program
    {
        static void Main(string[] args)
        {
            KitchenStaff newKitchen = new KitchenStaff();
            newKitchen.getBakers();
            newKitchen.getBaristas();
            newKitchen.getCooks();
            Console.ReadLine();

            KitchenDuties newKitchen1 = new KitchenDuties();
            newKitchen1.getBakers();
            newKitchen1.getBaristas();
            newKitchen1.getCooks();
            Console.ReadLine();
        }
    }

    interface Bakers
    {
        void getBakers();
    }
    interface Cooks
    {
        void getCooks();
    }
    interface Baristas
    {
        void getBaristas();
    }

    class KitchenInfo
    {
        private string m_kitchen_name = "";
        private Int16 m_bakers = 0;
        private Int16 m_baristas = 0;
        private Int16 m_cooks = 0;

        public string Name
        {
            get
            {
                return m_kitchen_name.ToString();
            }
            set
            {
                m_kitchen_name = value;
            }
        }
        public string Bakers
        {
            get
            {
                return m_bakers.ToString();
            }
            set
            {
                m_bakers = Convert.ToInt16(value);
            }
        }
        public string Baristas
        {
            get
            {
                return m_baristas.ToString();
            }
            set
            {
                if (value != string.Empty)
                {
                    m_baristas = Convert.ToInt16(value);
                }
            }
        }
        public string Cooks
        {
            get
            {
                return m_cooks.ToString();
            }
            set
            {
                if (value != string.Empty)
                {
                    m_cooks = Convert.ToInt16(value);
                }
            }
        }
    }

    class KitchenStaff : KitchenInfo, Bakers, Cooks, Baristas
    {
        public KitchenStaff()
        {
            Console.WriteLine("What is this kitchens name?");
            Name = Console.ReadLine();

            Console.WriteLine("How many bakers?");
            Bakers = Console.ReadLine();

            Console.WriteLine("How many baristas?");
            Baristas = Console.ReadLine();

            Console.WriteLine("How many cooks?");
            Cooks = Console.ReadLine();
        }
        public void getBakers()
        {
            System.Console.WriteLine("In {0} there are {1} bakers.", Name, Bakers);
        }
        public void getBaristas()
        {
            System.Console.WriteLine("In {0} there are {1} baristas.", Name, Baristas);
        }
        public void getCooks()
        {
            System.Console.WriteLine("In {0} there are {1} cooks.", Name, Cooks);
        }
    }
    class KitchenDuties : KitchenInfo, Bakers, Cooks, Baristas
    {
        public KitchenDuties()
        {
            Console.WriteLine("What is this kitchens name?");
            Name = Console.ReadLine();

            Console.WriteLine("How many bakers?");
            Bakers = Console.ReadLine();

            Console.WriteLine("How many baristas?");
            Baristas = Console.ReadLine();

            Console.WriteLine("How many cooks?");
            Cooks = Console.ReadLine();
        }
        public void getBakers()
        {
            System.Console.WriteLine("In {0}, the {1} bakers make fattening cookies.", Name, Bakers);
        }
        public void getBaristas()
        {
            System.Console.WriteLine("In {0}, the {1} baristas serve hot coffee.", Name, Baristas);
        }
        public void getCooks()
        {
            System.Console.WriteLine("In {0}, the {1} cooks make tender steak.", Name, Cooks);
        }
    }
}

從概念上講,您似乎並不了解界面。

雖然C#中的接口具有特定含義,但更常見的是在任何面向對象語言(包括C ++)中,您可以討論類的“公共接口”。 這基本上是另一個類可以看到的:它看不到私有成員,也看不到方法的內容,它只能看到其公共成員的簽名

例如,如果我有一個班級:

public class MyClass
{
    private int _myPrivateInt;
    public int MyPublicInt;

    private void DoSomethingPrivate(int input)
    {
        //Some code goes here
    }

    public void DoSomethingPublic(int input)
    {
        //Some more code goes here
    }
}

對於另一個班級而言,“可見”的所有內容將是:

int MyPublicInt;
void DoSomethingPublic(int input);

這是為了封裝 - 一個類不應該關心另一個類的具體實現細節。 MyClass公開聲明其他類需要知道如何與它進行交互,並保留其他所有內容。

這就是接口實際上是什么的想法,而在C#中,接口幾乎是一種在沒有公共方法的情況下僅僅指定信息的方法。 要了解原因,您需要了解相關概念, 多態性 考慮這些類:

public class InMemoryCustomerDataStorage
{
    public void StoreCustomerInfo(CustomerInfo info)
    {
        //Actual implementation goes here
    }

    public CustomerInfo RetrieveCustomerInfo(int customerId)
    {
        //Actual implementation goes here
    }
}

public class DatabaseCustomerDataStorage
{
    public void StoreCustomerInfo(CustomerInfo info)
    {
        //Actual implementation goes here
    }

    public CustomerInfo RetrieveCustomerInfo(int customerId)
    {
        //Actual implementation goes here
    }
}

public class FileCustomerDataStorage
{
    public void StoreCustomerInfo(CustomerInfo info)
    {
        //Actual implementation goes here
    }

    public CustomerInfo RetrieveCustomerInfo(int customerId)
    {
        //Actual implementation goes here
    }
}

這三者都有相同的目的,但方式不同。 它們都允許您存儲客戶信息,並通過ID檢索它。 他們可能還有其他我沒有寫過的私人成員,例如,文件可能有一個創建文件的方法,如果它還不存在,等等。他們都會有實際的實現,而不是那些評論,當然,我不是完全寫出來的,因為它只是一個例子。

那么界面怎么會在這里派上用場呢? 重點是程序的某些部分可能想要存儲和檢索客戶信息,但不關心它是如何完成的。 事實上,一般來說,除非他們直接需要照顧,否則他們不應該具體說明如何存儲它。 如果程序增長,您需要更改使用哪種類型的存儲? 您必須找到您編寫InMemoryCustomerDataStorage每個地方,並將其替換為DatabaseCustomerDataStorage 或者,如果您想在大多數時間使用數據庫,但是在測試代碼時,您希望在內存存儲中使用它以便快速運行? 您甚至可以編寫一個需要進行數據存儲的庫,但本身並不包含數據存儲類。 解決方案是使用接口。 你寫的:

public interface ICustomerDataStorage
{
    void StoreCustomerInfo(CustomerInfo info);
    CustomerInfo RetrieveCustomerInfo(int customerId);
}

然后在一個需要做一些客戶數據存儲的類中可能是這樣的:

public class NewCustomerProcessor
{
    private ICustomerDataStorage _storage;

    public NewCustomerProcessor(ICustomerDataStorage storage)
    {
        _storage = storage;
    }

    public void Process(string name, string address, string email, int age)
    {
        CustomerInfo info = new CustomerInfo(name, address, email, age);
        if(Validate(info))
            _storage.StoreCustomerInfo(info);
    }

    private bool Validate(CustomerInfo info)
    {
         //Some validation logic
    }
}

現在這個類是完全可用的,並且在任何時候都不必擔心使用ICustomerDataStorage的具體實現。 它可以存儲在內存中,文件中,數據庫中,它並不關心。 實現ICustomerDataStorage的類可以在一個完全不同的程序集和項目中,我可以將我的項目放在github上,下載它以在自己的項目中使用的人可以編寫自己的ICustomerDataStorage實現。

不,它與頭文件不相似。 C ++有頭文件和cpp文件,因此可以拆分聲明和定義。 C#將這些結合起來,因此您沒有單獨的聲明。

C# Interface在C ++中沒有直接的等價物。 最接近的是C ++中的抽象虛擬類。

不,它們不像C / C ++中的標題。 它是用於“現代”語言(如C#和Java)的概念。 它允許每個類繼承一組特征。

它是純抽象類,除了要為繼承提供的方法聲明之外,它不包含任何代碼。

最常見的示例是C#中的IEnumerable接口,它允許您在新定義的類對象上使用foreach語句。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM