为什么界面只有公共成员和方法

时间:2014-09-02 08:28:27

标签: c#

这是一个非常基本的访谈问题,我们可以将一个方法声明为私有内部界面,我的答案很简单,界面只有公共变量或方法然后接下来的问题......为什么?

4 个答案:

答案 0 :(得分:2)

接口具有某种实现提供的公共合同语义。它就像API的类(或全局模块,子系统,组件......)对其客户端有利。 私有方法用于处理一些内部逻辑,因此取决于实际的实现。它取决于上下文。因此,如果类客户端需要调用私有方法,而不是1)它必须是公共的或2)有一个糟糕的设计实践。

这就是为什么作为抽象接口可以被视为OOP的基础,它是实现抽象,封装和多态等事物的重要工具。

答案 1 :(得分:1)

接口是类需要实现的契约,以确保某个给定类的使用者将接收强制实现接口的类的实例。

如果接口允许私有成员,那么你无法调用从公共表面隐藏的接口成员这一事实将破坏接口的目的,因为消费者将无法调用这些私有成员(< em> so ...为什么会使用界面?)。

例如,接口提供对象的键入。如果某些消费者代码依赖于接收实现某个接口的对象以避免对使用它的程序集的冗余依赖性,并且整个程序集可以访问不公开提供成员的接口,那么该消费者将如何使用所谓的对象?

public interface IDoesSomething
{
     private void Do();
} 

public void SomeMethod(IDoesSomething some) 
{
    some.????? // <---- what? the object doesn't have public members!
}

事实上,由于接口只是元数据,我理解您可能会认为“我会声明私有成员强制实施者按预期的顺序调用某些逻辑”,但同样,因为他们'仅仅是元数据,您无法确保某些公共成员以正确的顺序呼叫私有成员。并且实现将无法访问接口私有成员,因为它们需要受保护这就是为什么抽象类存在)...

答案 2 :(得分:1)

关于界面成员如何具有不同的可见性有各种解释。虽然标识符的可见性可能有更多可想象的级别,但让我们看看C#中可用的级别,并考虑它们是否可以有意义地集成到接口中。

1)界面成员只能根据相应可见性级别的规则对界面外的代码可见。

  • public:默认情况下,C#中的接口成员是公共的,因此可行。
  • internal:如果单个接口成员可以声明为internal,则意味着接口的一部分只能由接口所在的程序集中的类实现。类似的情况在抽象类成员或抽象类的构造函数被声明为internal的情况下已经存在 - 这有效地防止了在基类的程序集之外的子类化。
    至于可能使用此方案的场景,请考虑返回后来被所述API再次使用的对象的API。如果由于某种原因,API只能使用它自己实例化的对象,能够以第三方代码无法派生自定义类的方式声明基类,而只使用它从API获取的内容,而不是能够对界面做同样的事情感觉奇怪的不对称。
  • protected:受保护的成员只能在自己的类及其任何子类中看到。应用与上面相同的假设,这意味着只有接口声明本身内的代码(好吧,一个接口几乎不包含任何与此相关的代码 1 )的派生接口(与之前相同) ),可能实现界面的类可以看到那些受保护的成员 后一种情况是事情可能变得有趣,如果只是在相当人为的情况下:该类中的方法可能想要消耗实现接口的任何东西,无论是类本身的当前实例,还是嵌套在其中的任何其他类型,获得对受保护方法的半独占访问权。
  • private:具有private可见性的所有内容仅对声明界面本身可见。由于接口成员几乎不能从接口本身引用 1 ,这可能不是非常有用。但是,可能仍然存在极端情况,例如接口中的const定义在所述接口的属性中引用,但不应该对外部代码可用 - 但是,C# does not allow for const values in interfaces,即使a similar feature is not unprecedented in the CLI world 3}}。

2)接口成员必须使用(至少?)接口中指定的可见性来实现,并且在通过键入类的引用访问成员时遵守该可见性,但在访问时通常是公开可见的成员通过键入接口的引用。

同样,public成员的情况不会发生变化,而internalprotectedprivate可见性将允许接口允许明显偏实现。目前可以通过显式接口实现来实现类似的效果,因此在某些方面,这将是语法糖,以避免两次写入相同的方法,一次使用预期的可见性,一次使用特定于接口的显式实现声明(即使后者通常只转发电话)。

3)为了完整起见,即使您的问题听起来不像包含此选项:对于每个类,整个界面的可见性由实现者确定。 < / p>

像这样,一个类可以实现一个接口,但是这个事实只会在相应的可见性级别内显而易见,而在外部,该类不会被认为是与该接口兼容的分配或可转换。
如果接口本身需要具有比类更低的可见性,这可能是特别有益的,因为接口应该仅在内部处理并且对于外部世界是没有意义的。 目前,这在C#中是不可能的;接口需要至少与它们的实现类一样可访问。但是,这也可以通过implementing an internal interface在公共类中实现。


由于有很多方法可以让界面成员的可见性变得可行,并且至少在某些情况下是有用的,对这个问题最明确的答案可能是&#34;因为开发团队决定指定C#这样&#34;

1 假设C#6的nameof运算符可以在同一接口的属性声明中的受保护/私有接口成员上使用。

答案 3 :(得分:-2)

答案太简单了;

当一个类从一个接口扩展时,这个接口的成员和方法应该可以被这个类访问,这就是为什么你必须公开