为什么我不能拥有受保护的接口成员?
在接口上声明受保护访问成员的参数是什么? 例如,这是无效的:
public interface IOrange { public OrangePeel Peel { get; } protected OrangePips Seeds { get; } }
在这个例子中, IOrange
接口将保证实现者至less向其inheritance者提供一个OrangePips
实例。 如果实施者想要的话,他们可以将范围扩大到public
:
public class NavelOrange : IOrange { public OrangePeel Peel { get { return new OrangePeel(); } } protected OrangePips Seeds { get { return null; } } } public class ValenciaOrange : IOrange { public OrangePeel Peel { get { return new OrangePeel(); } } public OrangePips Seeds { get { return new OrangePips(6); } } }
protected
成员在接口上的意图是为inheritance者 (子类)提供支持合同,例如:
public class SpecialNavelOrange : NavelOrange { ... // Having a seed value is useful to me. OrangePips seeds = this.Seeds; ... }
(无可否认,这不适用于struct
s)
我在接口中看不到private
或internal
修饰符的情况,但支持public
和protected
修饰符似乎是完全合理的。
我将尝试通过将interface
s与interface
s完全分开来解释protected
成员在interface
s上的效用:
让我们设想一个新的C#关键字, support
,强制inheritance者合同,以便我们声明如下:
public support IOrangeSupport { OrangePips Seeds { get; } }
这将允许我们合同类提供受保护的成员给他们的inheritance人:
public class NavelOrange : IOrange, IOrangeSupport { public OrangePeel Peel { get { return new OrangePeel(); } } protected OrangePips Seeds { get { return null; } } }
这并不是特别有用,因为类首先提供protected
成员就意味着这个合同。
但是,我们也可以这样做:
public interface IOrange : IOrangeSupport { ... }
从而将IOrangeSupport
应用于实现IOrange
所有类,并要求它们提供特定的protected
成员 – 这是我们目前不能做的事情。
我认为每个人都只是公开的接口,没有实现的细节。 你在找什么是抽象类 。
public interface IOrange { OrangePeel Peel { get; } } public abstract class OrangeBase : IOrange { protected OrangeBase() {} protected abstract OrangePips Seeds { get; } public abstract OrangePeel Peel { get; } } public class NavelOrange : OrangeBase { public override OrangePeel Peel { get { return new OrangePeel(); } } protected override OrangePips Seeds { get { return null; } } } public class ValenciaOrange : OrangeBase { public override OrangePeel Peel { get { return new OrangePeel(); } } protected override OrangePips Seeds { get { return new OrangePips(6); } } }
编辑:这是公平的,争辩说,如果我们有一个从类装饰派生的PlasticOrange,它只能实现IOrange,而不是种子保护的方法。 没事儿。 根据定义,接口是调用者和对象之间的契约,而不是在类和它的子类之间。 抽象类和我们这个概念一样接近。 这很好。 你基本上提出的是另一种语言构造,通过它我们可以在不破坏构build的情况下将子类从一个基类切换到另一个基类。 对我来说,这是没有意义的。
如果你正在创build一个类的子类,那么这个子类是基类的一个专门化。 它应该完全知道基类的任何受保护的成员。 但是,如果你突然想要切换基类,那么子类应该与任何其他IOrange一起工作是没有意义的。
我想你有一个公平的问题,但似乎是一个angular落的情况下,我不认为这是诚实的任何好处。
不明白为什么要这样做。 如果您希望派生类提供特定方法的实现,请参阅抽象基类。 接口就是这样 – 接口。 公共契约,没有别的。 将接口视为规范,描述了实现对外部世界应如何看待。 一个双引脚插头的规范没有说明(至less我假设)它的内部结构应该是什么样的。 它只是必须与sockets兼容。 插头http://www.made-in-china.com/image/2f0j00MCetlafAYTWcM/Two-Round-pin-Plug-with-Power-Wire.jpg
因为这是没有意义的。 一个接口是一个公开的合同。 我是一个IThing,因此如果询问我将执行IThing方法。 你不能要求IThing来确认它执行它不能告诉你的方法。
接口成员是一个公共API; 像protected
东西等是实现细节 – 接口没有任何实现。 我怀疑你正在寻找的是明确的接口实现:
public class NavelOrange : IOrange { public OrangePeel Peel { get { return new OrangePeel(); } } OrangePips IOrange.Seeds { get { return null; } } }
接口的存在允许人们在不知道具体实现是什么的情况下访问你的类。 它完全与数据传递契约的执行有分歧。
因此,界面中的所有内容都必须公开。 非公开成员只有在有权访问实现的情况下才有用,因此不会对接口定义做出有意义的贡献。
接口是向客户承诺特定function的合同。 换句话说,接口的目的是能够将types转换为types,并将其传递到需要该接口保证的特性的代码。 由于types的客户端代码无法访问该types的受保护成员,因此在接口中声明受保护的项目是没有意义的。
界面就像一个键的形状 。
这不是关键。
这不是锁。
这只是苗条的接触点。 (简单!)
出于这个原因,界面的所有成员(定义键的形状)必须是公开的。
对于打开锁的钥匙来说,重要的是它们都具有相同的形状。
通过公开形状(界面),可以让其他人创build兼容的锁或兼容的键。
否则,使它(接口)在内部不允许其他人创build兼容的锁或兼容的密钥。
一个接口是关于某个对象可以做什么的,所以当使用实现这个接口的类时,开发人员会期望所有成员都被实现,所以受保护的访问修饰符对于接口来说并不意味着什么。
在目前的接口devise中有很好的判断力,它为实现者提供了更大的灵活性。 请记住,接口通常是由框架程序员编写的,实现者是不同的人。 强制执行将是不必要的苛刻。
通过实现一个接口,types声明它支持一组特定的方法。 如果这些方法中的任何一个都不公开,那么调用者将无法使用这些方法,因此types将不支持所述的接口。
一个接口只包含公共成员。 受保护的手段无论你声明只适用于类和派生类实例。
任何实现.net接口的类都必须包含所有接口成员的实现。 此外,任何类都可以暴露给派生类,无论它希望如何。 要求一个接口的实现必须包含一个只能从派生类中使用的成员,除非(1)这样一个成员对接口外部的东西可见,或者(2)接口实现可以使用他们没有自己定义的成员。 如果接口允许包含嵌套类(可以访问接口的protected
成员),那么protected
接口成员将是合理的。 事实上,如果嵌套在接口中的类可以定义该接口的扩展方法,那么它们可能非常有用。 不幸的是,这样的设施不存在。
顺便说一句,即使不能在接口中嵌套类,将internal
访问修饰符应用于接口成员仍然有用,其效果是只有定义了接口的程序集才能够为其定义任何实现。