强制使用接口而不是声明中的具体实现(.NET)
在C ++中,您可以执行以下操作:
class base_class { public: virtual void do_something() = 0; }; class derived_class : public base_class { private: virtual void do_something() { std::cout << "do_something() called"; } };
derived_class
重写方法do_something()
并将其derived_class
private
。 结果是,调用此方法的唯一方法是这样的:
base_class *object = new derived_class(); object->do_something();
如果将对象声明为derived_class
类型,则无法调用该方法,因为它是私有的:
derived_class *object = new derived_class(); object->do_something(); // --> error C2248: '::derived_class::do_something' : cannot access private member declared in class '::derived_class'
我认为这很好,因为如果你创建一个用作接口的抽象类,你可以确保没有人意外地声明一个字段作为具体类型,但总是使用接口类。
因为在C#/ .NET中,一般情况下,在覆盖方法时,不允许缩小从public
到private
的访问,有没有办法在这里实现类似的效果?
如果您明确实现了一个接口,这至少会鼓励人们在声明中使用接口类型。
interface IMyInterface { void MyMethod(); } class MyImplementation : IMyInterface { void IMyInterface.MyMethod() { } }
在将实例强制转换为IMyInterface之后,只能看到MyMethod。 如果声明使用接口类型,则后续使用中不需要转换。
关于显式接口实现的MSDN页面 (感谢Luke,节省了几秒钟^^)
IMyInterface instance = new MyImplementation(); instance.MyMethod(); MyImplementation instance2 = new MyImplementation(); instance2.MyMethod(); // Won't compile with an explicit implementation ((IMyInterface)instance2).MyMethod();
您也可以使用显式接口实现在.Net世界中执行此操作
作为示例, BindingList
实现IBindingList
,但您必须将其IBindingList
转换为IBindingList
才能查看该方法。
您可以通过将方法标记为new
来减少方法的可用性。
来自MSDN的CA2222的示例:不要降低inheritance的成员可见性 :
using System; namespace UsageLibrary { public class ABaseType { public void BasePublicMethod(int argument1) {} } public class ADerivedType:ABaseType { // Violates rule: DoNotDecreaseInheritedMemberVisibility. // The compiler returns an error if this is overridden instead of new. private new void BasePublicMethod(int argument1){} } }
作为一项学术活动,这真的更有趣; 如果您的代码真的依赖于无法在BasePublicMethod
上调用BasePublicMethod
, ADerivedType
这是一个可疑设计的警告信号。
如果实施该策略,问题在于该方法不是真正私有的。 如果要向上转换对base_class
的引用,则该方法现在是公共的。 由于它是一个虚方法,用户代码将执行derived_class::do_something()
尽管它被标记为私有。