C#接口的非公共成员
在C#中,实现接口时,所有成员都是隐式公共的。如果可以指定可访问性修饰符(当然是" protected"," internal",当然要是" private"除外)会更好,还是应该只使用抽象类呢?
解决方案
回答
没道理。接口是我们与公众签订的支持这些方法和属性的合同。坚持抽象类。
回答
接口的方法中没有访问修饰符,因此可以使用任何合适的访问修饰符。这有一个目的:它允许其他类型推断出接口后对象可使用的方法和属性。为它们提供受保护的/内部的访问器会破坏接口的目的。
如果我们坚决需要为方法提供访问修饰符,则可以将其保留在接口之外,或者如我们所说,使用抽象类。
回答
我熟悉Java而不是C#,但是为什么我们会希望在接口中加入私有成员呢?它不可能有任何实现,并且对于实现类是不可见的,因此将毫无用处。存在用于指定行为的接口。如果我们需要默认行为,则可以使用抽象类。
回答
如果接口是内部接口,则其所有成员都将是部件的内部接口。如果嵌套接口受保护,则只有外部类的子类才能访问该接口。
在其声明程序集外部的接口的内部成员将毫无意义,在其声明外部类外部的接口的受保护成员也将毫无意义。
接口的重点是描述接口的实现类型和用户之间的协定。外部呼叫者将不必在乎,也不必在乎实现,这是内部成员和受保护成员的目的。
对于由基类调用的受保护成员,抽象类是在基类和从其继承的类之间指定契约的方法。但是在这种情况下,实现细节通常非常相关,除非它是退化的纯抽象类(所有成员都是抽象类),在这种情况下,受保护的成员是无用的。在这种情况下,请使用接口并保存单个基类以实现选择的类型。
回答
我们可以通过在方法名称之前显式说明接口名称来隐藏接口的实现:
public interface IInterface { public void Method(); } public class A : IInterface { public void IInterface.Method() { // Do something } } public class Program { public static void Main() { A o = new A(); o.Method(); // Will not compile ((IInterface)o).Method(); // Will compile } }
回答
接口是所有实现类都遵守的契约。这意味着他们必须遵守所有规则或者不遵守任何规则。
如果该接口是公开的,则该联系人的每个部分都必须是公开的,否则对朋友/内部类来说意味着一个,而对其他所有事物则意味着不同。
在接口上使用抽象基类或者(如果可能且可行)内部扩展方法。
回答
我们可以隐藏几乎所有由外部程序集的接口实现的代码。
interface IVehicle { void Drive(); void Steer(); void UseHook(); } abstract class Vehicle // :IVehicle // Try it and see! { /// <summary> /// Consuming classes are not required to implement this method. /// </summary> protected virtual void Hook() { return; } } class Car : Vehicle, IVehicle { protected override void Hook() // you must use keyword "override" { Console.WriteLine(" Car.Hook(): Uses abstracted method."); } #region IVehicle Members public void Drive() { Console.WriteLine(" Car.Drive(): Uses a tires and a motor."); } public void Steer() { Console.WriteLine(" Car.Steer(): Uses a steering wheel."); } /// <summary> /// This code is duplicated in implementing classes. Hmm. /// </summary> void IVehicle.UseHook() { this.Hook(); } #endregion } class Airplane : Vehicle, IVehicle { protected override void Hook() // you must use keyword "override" { Console.WriteLine(" Airplane.Hook(): Uses abstracted method."); } #region IVehicle Members public void Drive() { Console.WriteLine(" Airplane.Drive(): Uses wings and a motor."); } public void Steer() { Console.WriteLine(" Airplane.Steer(): Uses a control stick."); } /// <summary> /// This code is duplicated in implementing classes. Hmm. /// </summary> void IVehicle.UseHook() { this.Hook(); } #endregion }
这将测试代码。
class Program { static void Main(string[] args) { Car car = new Car(); IVehicle contract = (IVehicle)car; UseContract(contract); // This line is identical... Airplane airplane = new Airplane(); contract = (IVehicle)airplane; UseContract(contract); // ...to the line above! } private static void UseContract(IVehicle contract) { // Try typing these 3 lines yourself, watch IDE behavior. contract.Drive(); contract.Steer(); contract.UseHook(); Console.WriteLine("Press any key to continue..."); Console.ReadLine(); } }