2014-02-20 66 views
1

昨天我询问this question,但我认为目前还不清楚我主要关心的是什么。在C++中,我们拥有私有继承和多重继承,这使我们可以通过继承声明这些方法的类来为类添加私有方法。也就是说,如果有一类在C#中通过继承向类中添加私有方法

class B { 
public: 
    virtual void doMethodB(); 
}; 

和一类

class A : private B { 
    virtual int doMethodA(); 
}; 

doMethodB()可以从doMethodA()中被调用,而不是从外部访问。

现在,我想在C#中模仿这种行为。没有多重或私人继承。就知道了,我能想到的四种方式来实现类似的财产以后,但仍然有严重的缺陷:

首先:使用interface,即

interface IB { 
    public void doMethodB(); 
}; 
class A : IB { 
    public void doMethodB(); 
    int doMethodA(); 
}; 

然而,我们这样做的时候,doMethodB()public,并且必须执行每个类继承IB

二:使用一个静态方法

public static class B { 
    public static void doMethodB(); 
}; 

这样一来,有仅需要一个实现,但该方法仍是公众,不能局限于某些类别。

第三:使用扩展方法,如that。然而,该方法在对象(即a.doMethodB())上而不是从“内部”上被称为

第四:构图。

class A { 
    private B b; 
    public int doMethodA(); 
}; 

现在,B的方法可以被称为像b.doMethodB()只从A,但其他的问题现在就系列化,b == null

难道还有其他选择吗?如果不是,你会考虑哪一个是“最好”

+1

由于私有继承基本上是遏制,为什么不简单地拥有'B'的私有成员变量? –

+0

您可以使用受保护的方法。 –

回答

2

关于具有接口的“第一个”提议:您也可以显式实现接口: “实现接口的类可以显式实现该接口的成员,当成员明确实现时,不能通过一个类实例,但只能通过一个接口实例。“ 请参阅/源代码:http://msdn.microsoft.com/en-us/library/aa288461%28v=vs.71%29.aspx

但是,我会选择合成方法。 “青睐组成了继承”,也看到Prefer composition over inheritance?

理想的情况下,由依赖注入,我会构造函数注入BA,这应该有助于减轻你的b == null关注。

注: 使用静态方法/扩展方法(是一个静态方法,也...),使单元测试A(分别为伪造B)很辛苦,这就是为什么我会完全放弃这些解决方案。

编辑: 如果您不需要B.doMethodB任何人比其他A访问,也可以使Babstract类和B.doMethodB一个protected方法。 但我一直在想,你已经知道;-) (由于测试问题,我仍然赞成组合继承)。

+0

您的提案与'abstract'类听起来很相像;我会试一试。它几乎是*我所需要的,尽管没有多重继承,它只能用于基类,而不能用于例如。一个'Windows.Form'我想? – Matz

+0

正确,有单一的继承,所以你不能有'A:B,Windows.Form'。但是,您可以拥有'B:Windows.Form'和'A:B'(从'Windows.Form'继承的'B'继承'A') – BatteryBackupUnit

1

我认为你正在寻找的概念是protected访问修饰符。这意味着只有B本身及其派生类可以访问该方法,但其他类不能。

class B { 
    protected virtual void DoMethodB() {} 
} 

class A : B { 
    virtual void DoMethodA() { 
     DoMethodB(); 
    } 
} 

如果你愿意,你可以进一步限制访问protected internal这意味着该方法只能从组件内的派生类访问。

另外,请注意虚拟方法的后果。如果没有明确的需要使方法变为虚拟的,则不应该将其标记为虚拟的。

+0

这是不一样的。在问题'B:doMethodB'是公开的,所以人们可以创建一个'B'的实例并调用'doMethodB'。在你的例子中,任何创建'B'实例的人都不能调用该方法,只有派生类可以。 – Sean

+0

@肖恩是的,但这无论如何都会与继承的性质是“一种”关系相冲突。 – Georg

+1

*私有*继承不是一种“是 - 一种”关系。 – Matz