假设我有公共方法A和B的BaseClass,我通过继承创建DerivedClass.
例如
public DerivedClass : BaseClass {}
现在我想在DerivedClass中开发一个使用A和B的方法C.有没有办法可以在DerivedClass中将方法A和B重写为私有,这样只有方法C才会暴露给想要使用我的DerivedClass的人?
这不可能,为什么?
在C#中,强制要求你如果继承了公共方法,就必须将它们公之于众.否则他们希望你不要从这个阶段派生出来.
您不必使用is-a关系,而是必须使用has-a关系.
语言设计者不会故意允许这样做,以便您更正确地使用继承.
例如,有人可能会意外地将类Car混淆为从类Engine派生以获得它的功能.但引擎是汽车使用的功能.所以你想要使用has-a关系.Car的用户不希望访问Engine的界面.汽车本身不应该将引擎的方法与它自己的方法混淆.Nor Car的未来派生.
所以他们不允许它保护你免受糟糕的继承层次结构的影响.
你应该怎么做?
相反,你应该实现接口.这使您可以使用has-a关系自由使用功能.
其他语言:
在C++中,您只需在private,public或protected的基类之前指定一个修饰符.这使得基础的所有成员都公开到指定的访问级别.对我来说,你不能在C#中做同样的事情似乎很愚蠢.
重组后的代码:
interface I { void C(); } class BaseClass { public void A() { MessageBox.Show("A"); } public void B() { MessageBox.Show("B"); } } class Derived : I { public void C() { b.A(); b.B(); } private BaseClass b; }
我理解上面这些类的名字有点没有实际意义:)
其他建议:
其他人建议将A()和B()公开并抛出异常.但是,这并没有为人们提供友好的课程,而且实际上没有意义.
例如,当您尝试从a继承时List
,您想要隐藏直接Add(object _ob)
成员:
// the only way to hide [Obsolete("This is not supported in this class.", true)] public new void Add(object _ob) { throw NotImplementedException("Don't use!!"); }
这不是最理想的解决方案,但它可以完成这项工作.Intellisense仍然接受,但在编译时你会收到一个错误:
错误CS0619:'TestConsole.TestClass.Add(TestConsole.TestObject)'已过时:'此类不支持此'.
这听起来像个坏主意.Liskov不会留下深刻印象.
如果您不希望DerivedClass的使用者能够访问方法DeriveClass.A()和DerivedClass.B(),我建议DerivedClass应该实现一些公共接口IWhateverMethodCIsAbout,并且DerivedClass的使用者实际上应该与IWhateverMethodCIsAbout交谈并且知道根本没有关于BaseClass或DerivedClass的实现.
你需要的是组合而不是继承.
class Plane { public Fly() { .. } public string GetPilot() {...} }
现在,如果您需要一种特殊的平面,例如具有PairOfWings = 2的平面,但平面可以做任何事情.您继承平面.通过这种方式,您声明您的派生符合基类的契约,并且可以替换而不会在期望基类的任何地方闪烁.例如,LogFlight(Plane)将继续使用BiPlane实例.
但是,如果您只需要想要创建的新Bird的Fly行为,并且不愿意支持完整的基类合约,那么您需要编写.在这种情况下,重构方法的行为以重用到新类型的Flight中.现在在Plane和Bird中创建并保持对此类的引用.你没有继承,因为Bird不支持完整的基类契约......(例如它不能提供GetPilot()).
出于同样的原因,您在覆盖时无法降低基类方法的可见性.您可以在派生中覆盖并使基本私有方法公开,但反之亦然.例如,在这个例子中,如果我派生出一种Plane"BadPlane",然后覆盖并"隐藏"GetPilot() - 将其设为私有; 一个客户端方法LogFlight(Plane p)适用于大多数Planes,但如果LogFlight的实现恰好需要/调用GetPilot(),它将会爆炸为"BadPlane".由于预期基类的所有派生都是"可替代的",无论何时需要基类参数,都必须禁止这种派生.