强制声明(.NET)使用接口而不是具体实现
在C++中,你可以做到以下几点:强制声明(.NET)使用接口而不是具体实现
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()
并使其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()
{
}
}
一个只会看到的MyMethod铸造实例IMyInterface
后。如果声明使用接口类型,则在随后的使用中不需要转换。
MSDN page on explicit interface implementation(感谢卢克,节省了我几秒钟^^)
IMyInterface instance = new MyImplementation();
instance.MyMethod();
MyImplementation instance2 = new MyImplementation();
instance2.MyMethod(); // Won't compile with an explicit implementation
((IMyInterface)instance2).MyMethod();
您是可以通过标记为new
来降低方法的可用性。
从MSDN's CA2222: Do not decrease inherited member visibility的例子:
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){}
}
}
这是作为一个学术活动真的很有趣;如果你的代码真的依赖于不能在ADerivedType
上调用BasePublicMethod
,那是一个可疑设计的警告信号。
您可以在.NET世界也做到这一点,利用explicit interface implementation
举个例子,BindingList<T>
实现IBindingList
,但你必须将它转换为IBindingList
看方法。
它被称为显式接口实现:http://msdn.microsoft.com/en-us/library/aa288461.aspx – LukeH 2010-05-05 11:24:07
@Luke感谢您的链接,我一直在努力寻找它:) – 2010-05-05 11:48:01
该策略应该实施的问题是该方法并非真正的私有方法。如果您想提及base_class
,那么该方法现在是公开的。由于它是一种虚拟方法,用户代码将会执行derived_class::do_something()
事件,尽管它被标记为私有。
在这种情况下,这不是一个错误,而是一个功能。 – sbi 2010-05-05 11:21:20
这个效果是我想要的,谢谢。 – gammelgul 2010-05-05 11:33:49
+1我刚刚学到了一些新东西! – BritishDeveloper 2010-05-05 11:44:32
+1谢谢你,也学到了新的东西! – Deano 2011-03-04 10:11:38