简体   繁体   English

接口和标头

[英]Interfaces and Headers

Today I ran across the concept of a C# Interface, I have one hopefully simple question to see if I understand them... Are they fairly similar to a C++ header file? 今天我遇到了C#接口的概念,我有一个希望很简单的问题,看看我是否理解它们......它们是否与C ++头文件非常相似? I mean, from what I'm getting, you define the backbone of a class without actually defining what it does, that's kind of similar to a header, correct? 我的意思是,从我得到的,你定义一个类的主干,而不是实际定义它的作用,这类似于标题,是正确的吗? I read the entire MSDN definition and it doesn't really make it 100% clear to me. 我阅读了整个MSDN定义,并没有真正让我100%清楚。 I believe I have the idea (wrote and attached a very elementary program to see if I understood) but it's pretty important that I at least fully understand the basics of them by tomorrow evening. 我相信我有这个想法(编写并附上了一个非常基本的程序,看看我是否理解)但是至少在明天晚上至少完全理解它们的基础知识是非常重要的。

Example: 例:

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

Conceptually it doesn't seem like you're understanding interfaces. 从概念上讲,您似乎并不了解界面。

While interface in C# has a specific meaning, more generally in any object-oriented language, including C++, you can talk about the 'public interface' of a class. 虽然C#中的接口具有特定含义,但更常见的是在任何面向对象语言(包括C ++)中,您可以讨论类的“公共接口”。 This is essentially what another class can see: it can't see private members, and it can't see the content of methods, it can only see the signatures of its public members. 这基本上是另一个类可以看到的:它看不到私有成员,也看不到方法的内容,它只能看到其公共成员的签名

So for example if I have a class: 例如,如果我有一个班级:

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

All that is 'visible' of that to a different class will be: 对于另一个班级而言,“可见”的所有内容将是:

int MyPublicInt;
void DoSomethingPublic(int input);

This is for the sake of encapsulation- one class shouldn't care about the specific implementation details of another class. 这是为了封装 - 一个类不应该关心另一个类的具体实现细节。 MyClass publicly declares just what other classes need to know how to interact with it, and keeps everything else to itself. MyClass公开声明其他类需要知道如何与它进行交互,并保留其他所有内容。

So that's the idea of what an interface actually is, and in C# an interface is pretty much a way to specify just that information without the public methods. 这就是接口实际上是什么的想法,而在C#中,接口几乎是一种在没有公共方法的情况下仅仅指定信息的方法。 To understand why, you need to understand a related concept, polymorphism . 要了解原因,您需要了解相关概念, 多态性 Consider these classes: 考虑这些类:

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

All three serve the same purpose, but in different ways. 这三者都有相同的目的,但方式不同。 They all allow you to store customer information, and retrieve it by an id. 它们都允许您存储客户信息,并通过ID检索它。 They may also have additional private members I haven't written out, for example the File one might have a method which creates the file if it doesn't already exist, etc. They would all have actual implementations rather than those comments, of course, I'm not writing them out fully because it's just an example. 他们可能还有其他我没有写过的私人成员,例如,文件可能有一个创建文件的方法,如果它还不存在,等等。他们都会有实际的实现,而不是那些评论,当然,我不是完全写出来的,因为它只是一个例子。

So how would an interface come in handy here? 那么界面怎么会在这里派上用场呢? Well the point is that parts of your program may want to store and retrieve customer information, but not care how it's done. 重点是程序的某些部分可能想要存储和检索客户信息,但不关心它是如何完成的。 In fact, generally speaking, they shouldn't specify exactly how to store it unless they directly need to care. 事实上,一般来说,除非他们直接需要照顾,否则他们不应该具体说明如何存储它。 What if as the program grows, you need to change which type of storage is used? 如果程序增长,您需要更改使用哪种类型的存储? You'd have to find every place you'd written InMemoryCustomerDataStorage and replace it with DatabaseCustomerDataStorage . 您必须找到您编写InMemoryCustomerDataStorage每个地方,并将其替换为DatabaseCustomerDataStorage Or what if you want to use a database most of the time, but when you're testing your code, you want to use in memory storage so that it runs fast? 或者,如果您想在大多数时间使用数据库,但是在测试代码时,您希望在内存存储中使用它以便快速运行? You could even be writing a library that needs to do data storage but doesn't itself include data storage classes. 您甚至可以编写一个需要进行数据存储的库,但本身并不包含数据存储类。 The solution to this is to use an interface. 解决方案是使用接口。 You'd write: 你写的:

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

Then inside a class that needed to do some customer data storage could be something like: 然后在一个需要做一些客户数据存储的类中可能是这样的:

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

Now this class is fully functional, and at no point does it have to worry about which concrete implementation of ICustomerDataStorage is used. 现在这个类是完全可用的,并且在任何时候都不必担心使用ICustomerDataStorage的具体实现。 It could be stored in memory, in a file, in a database, it doesn't care. 它可以存储在内存中,文件中,数据库中,它并不关心。 The class that implements ICustomerDataStorage could be in an entirely different assembly and project, I could put my project on github, and whoever downloads it to use in their own project could write their own implementation of ICustomerDataStorage. 实现ICustomerDataStorage的类可以在一个完全不同的程序集和项目中,我可以将我的项目放在github上,下载它以在自己的项目中使用的人可以编写自己的ICustomerDataStorage实现。

No, it is not similar to a header file. 不,它与头文件不相似。 C++ has header files and cpp files so that the declaration and definition can be split. C ++有头文件和cpp文件,因此可以拆分声明和定义。 C# combines those so you don't have a separate declaration. C#将这些结合起来,因此您没有单独的声明。

C# Interface does not have a direct equivalent in C++. C# Interface在C ++中没有直接的等价物。 The closest thing would be an abstract virtual class in C++. 最接近的是C ++中的抽象虚拟类。

No, they are not anything like headers in C/C++. 不,它们不像C / C ++中的标题。 It is concept used in "modern" languages like C# and Java. 它是用于“现代”语言(如C#和Java)的概念。 It allows every class to inherit set of characteristics. 它允许每个类继承一组特征。

It is pure abstract class, that doesn't contain any code besides declaration of methods you want to make available for inheriting. 它是纯抽象类,除了要为继承提供的方法声明之外,它不包含任何代码。

Most common example is IEnumerable interface in C# that allows you to use foreach statement on your newly defined class object. 最常见的示例是C#中的IEnumerable接口,它允许您在新定义的类对象上使用foreach语句。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM