6

在 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()使其成为private. 效果是,调用此方法的唯一方法是这样的:

base_class *object = new derived_class();
object->do_something();

如果将对象声明为 type 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 中,不允许在覆盖方法时缩小访问范围publicprivate有没有办法在这里实现类似的效果?

4

4 回答 4

15

如果你显式地实现一个接口,这至少会鼓励人们在声明中使用接口类型。

interface IMyInterface
{
    void MyMethod();
}

class MyImplementation : IMyInterface
{
    void IMyInterface.MyMethod()
    {
    }
}

只有在将实例转换为IMyInterface. 如果声明使用接口类型,则在后续使用中不需要强制转换。

关于显式接口实现的 MSDN 页面(感谢 Luke,为我节省了几秒钟的时间^^)

IMyInterface instance = new MyImplementation();
instance.MyMethod();

MyImplementation instance2 = new MyImplementation();
instance2.MyMethod();  // Won't compile with an explicit implementation
((IMyInterface)instance2).MyMethod();
于 2010-05-05T11:23:57.433 回答
4

您也可以在 .Net 世界中执行此操作,使用显式接口实现

例如,BindingList<T>implements IBindingList,但您必须将其强制转换IBindingList才能看到该方法。

于 2010-05-05T11:19:22.817 回答
2

可以通过将其标记为 来降低方法的可用性new

来自MSDN 的 CA2222 的示例:不要降低继承的成员可见性

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){}       
    }
}

作为一项学术练习,这确实更有趣;如果您的代码确实依赖于无法调用BasePublicMethodADerivedType那是可疑设计的警告信号。

于 2010-05-05T11:18:57.897 回答
0

如果实施此策略,问题在于该方法不是真正私有的。如果您要向上转换对 的引用base_class,那么该方法现在是公开的。由于它是一个虚拟方法,derived_class::do_something()即使它被标记为私有,用户代码也会执行。

于 2010-05-05T11:19:32.733 回答