接口和标头

时间:2014-03-27 19:33:41

标签: c# c++ inheritance interface

今天我遇到了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);
        }
    }
}

3 个答案:

答案 0 :(得分:9)

从概念上讲,您似乎并不了解界面。

虽然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#中,接口几乎是一种在没有公共方法的情况下仅仅指定信息的方法。要了解原因,您需要了解相关概念 polymorphism 。考虑这些类:

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实现。

答案 1 :(得分:0)

不,它与头文件不相似。 C ++有头文件和cpp文件,因此可以拆分声明和定义。 C#结合了这些,所以你没有单独的声明。

C#Interface在C ++中没有直接的等价物。最接近的是C ++中的抽象虚拟类。

答案 2 :(得分:0)

不,它们与C / C ++中的标题不同。 它是用于“现代”语言(如C#和Java)的概念。它允许每个类继承一组特征。

它是纯抽象类,除了要用于继承的方法声明之外,它不包含任何代码。

最常见的例子是C#中的IEnumerable接口,它允许您在新定义的类对象上使用foreach语句。