如何隐藏一个对象的受保护过程?

7
在一个基类中,有一个protected过程。当继承该类时,我想隐藏该过程以防止从外部使用它。我尝试在privatestrict private部分内重写它,但仍然可以从外部调用。原始类不是我的,所以我无法更改TOriginal的定义。
是否可能在我的继承类中隐藏此过程?如何实现?
type
  TOriginal = class(TObject)
  protected
    procedure SomeProc;
  end;

  TNew = class(TOriginal)
  strict private
    procedure SomeProc; override;
  end;

2
如果您想要隐藏基类的方法,使其不被派生类继承,那么您需要将其声明在私有部分; 私有方法只能被本类访问; 受保护的方法可以被本类和派生类访问; 最后,公共或发布的方法对所有人都可见;发布与公共相同,但此部分用于 Delphi IDE,以便在对象检查器中显示组件属性。 - teran
2
什么阻止代码使用您的派生类将引用转换为基类引用或分配它们?获得访问任何“隐藏”方法的权限?您想要的是无法实现的。如果您有这样的冲动,那么继承关系就完全错误了。 - mghie
1
为什么会有踩票?这似乎是一个合理的问题,符合常见问题解答并且可以回答。当然,它有点误导(违反了“面向对象编程”),但这可以在回答中解决! - Cosmin Prund
2
@Jerry:我也是这么认为的。这意味着如果你无法接受它的接口,就不应该继承那个类。请阅读关于Liskov替换原则的文章(http://en.wikipedia.org/wiki/Liskov_substitution_principle)。也许在你的情况下,组合比继承更好? - mghie
我没有提及原始的*基础(base)类,因为我试图去人格化(depersonalize)*我提出的问题;这意味着我试图突出问题的范围,而不涉及任何个人命名、用法等。我的目标是讨论类成员的访问级别这一普遍主题。 - Jerry Dodge
显示剩余4条评论
2个回答

11

保护方法已经从外部隐藏。(大多数情况下,见下文)你不能降低类成员的可见性。如果基类声明该方法为保护的,则该类的所有派生类都可以使用该方法。


在Delphi中,与类相同单元的其他代码可以访问该类的受保护成员,即使是来自无关类的代码也可以。有时这是有用的,但通常是为了解决设计缺陷。如果您有一些"真正、真正"应该受保护的东西,您可以将其设为严格保护,那么特殊的同一单元访问规则就不适用了。


使用“类助手”仍然可以访问严格受保护/私有成员。 - LU RD
@LURD,只要没有“单元助手”,就无法访问私有成员。 - OnTheFly
原始类(TOriginal)不是我的类,所以我无法简单地更改它。进一步研究原始类,我发现SomeProc在家族中的上层实际上是公共的,但是这个我正在继承的类已经将其移动到了protected,这就解释了为什么我能够访问它。那么一旦某些东西被公开,它就无法被取消公开了吗? - Jerry Dodge

1

一旦暴露,你就无法隐藏它,但你可以以有限的方式定位它被调用的位置

TOriginalClass = class
public
  procedure Foo;
end;

TNewClass = class(TOriginalClass) 
public
  procedure Foo; reintroduce;
end;

implementation

procedure TNewClass.Foo;
begin
  Assert(False, 'Do not call Foo from this class');
  inherited Foo;
end;

var Obj: TNewClass;
Obj := TNewClass.Create;
Obj.Foo; // get assert message

Will not get Assert error if declared as TOriginalClass
var Obj: TOriginalClass;
Obj := TNewClass.Create;
Obj.Foo; // Never get the assert message

谢谢您的回复,我有点理解了,但我不明白这个类似C语言的语法是从哪里来的... 这看起来不像是纯Delphi代码... - Jerry Dodge
虽然我理解你的观点,但代码还是有些不妥。主要问题在于两个类都将 Foo 声明为 public,这很可疑。 - Jerry Dodge

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接