Delphi 如何在类具有重载的TObject构造函数时隐藏继承的TObject构造函数?
看看这个课程:Delphi 如何在类具有重载的TObject构造函数时隐藏继承的TObject构造函数?,delphi,Delphi,看看这个课程: TTest = class(TObject) public constructor Create(A:Integer);overload; constructor Create(A,B:Integer);overload; end; 现在,当我们要使用该类时: var test: TTest; begin test:= TTest.Create; //this constructor is still visible and usa
TTest = class(TObject)
public
constructor Create(A:Integer);overload;
constructor Create(A,B:Integer);overload;
end;
现在,当我们要使用该类时:
var
test: TTest;
begin
test:= TTest.Create; //this constructor is still visible and usable!
end;
有人能帮我隐藏这个构造函数吗?您可以通过引入一个非重载的Create来隐藏继承的Create。由于需要两个重载的Create,您可以使用可选的第二个参数将它们合并到一个Create中:
TTest = class(TObject)
public
constructor Create(A:Integer; B: Integer = 0);
end;
这将发出编译器警告,表明您正在隐藏默认的无参数构造函数。要消除警告,您可以像这样声明隐藏构造函数:
TTest = class(TObject)
public
constructor Create(A:Integer; B: Integer = 0); reintroduce;
end;
或者,如果这不可行,您可以引入一个中间类,引入第一个create,然后引入最后一个重载的第二个类:
preTest = class(TObject)
public
constructor Create(A:Integer); reintroduce;
end;
TTest = class(preTest)
public
constructor Create(A,B:Integer);overload;
end;
只要有名为
Create
的重载构造函数,从TObject
派生时就不能隐藏无参数的TObject
构造函数
这里讨论了这一点:
如果您准备在类和TObject
之间放置另一个类,您可以使用:
另一个选项是在运行时使用
不推荐的
关键字和引发
异常
TTest=class(TObject)
公开的
构造函数创建;超载;不推荐使用的“TTest类不支持无参数构造函数”;
构造函数创建(常量A:整数);超载;
构造函数创建(常量A,B:整数);超载;
结束;
实施
构造函数test.Create;
开始
引发异常。Create('TTest类不支持无参数构造函数');
结束;
通过两个继承,可以从设计时而不是运行时阻止用户创建TMySingleton类
unit MySingleton;
interface
uses System.Classes, System.SysUtils;
type
// Constructor Block external access
THideConstructor = class abstract
strict protected
constructor Create; virtual; abstract;
end;
// Switching the access to the Create function THideConstructor in TObject through the constructor Overloading
// Declaring Create Method as a procedure to prevent class call-TMySingle.Create('string') call impossible
TOverloadConstructor = class(THideConstructor)
public
procedure Create(s: string); reintroduce; overload; deprecated 'null method';
end;
TMySingleton = class sealed(TOverloadConstructor)
private
class var MyObj: TMySingleton;
strict protected
// Hiding TOverloadConstructor.Create(s: string);
// Implement THideConstructor.Create
constructor Create; override;
public
class function Obj: TMySingleton;
function Echo(const value: string): String;
destructor Destroy; override;
end;
implementation
{ TMySingleton }
constructor TMySingleton.Create;
begin
// TODO
end;
destructor TMySingleton.Destroy;
begin
Self.MyObj := nil;
inherited;
end;
function TMySingleton.Echo(const value: string): String;
begin
result := value;
end;
class function TMySingleton.Obj: TMySingleton;
begin
if MyObj = nil then
MyObj := Self.Create;
result := MyObj;
end;
{ TOverloadContructor }
procedure TOverloadConstructor.Create(s: string);
begin
// null method
end;
initialization
TMySingleton.MyObj := nil;
finalization
if Assigned(TMySingleton.MyObj) then
FreeAndNil(TMySingleton.MyObj);
end.
如果用户
var
Singleton: TMySingleton;
begin
Singleton := TMySingleton.Create;
出现设计时错误
[dcc32 Error] Unit1.pas(33): E2625 Private member 'THideConstructor.Create' is inaccessible here MySingleton.pas(11): Related method: constructor Create;
此外,您看不到任何名为“创建”的自动完成提示。您为什么要这样做?你想达到什么目标?+1。我以为以前有人问过这个问题,但我发现唯一的问题并没有这么简单。@Marjan Venema:很明显,我想创建一个标准类,我的类不应该有这个默认构造函数。我不想与我正在使用的语言/框架作斗争。只需使用reintroduce声明它(有效地隐藏了默认值)。是否引发异常和/或将其标记为不推荐?如果编译器接受不推荐使用的代码,那么您将收到编译时警告和其他运行时异常。但我看到David刚刚用一些有趣的想法扩展了他的答案。您可以让编译器对此进行阻止。Create或TObject是否有特殊之处,或者此规则是否适用于与非重载、非虚拟基方法同名的所有重载方法?它是通用的。派生类(即每个类)中的任何重载方法都会自动使继承的方法也重载。@Rob据我所知,构造函数,
Create
,TObject
没有什么特别之处。同样的行为可以用普通方法复制;在子类中。好的,我讨论得有点晚了,但是第一个代码片段不会引起警告,因为TObject.Create
不是虚拟的或动态的。这也是为什么重新引入
没有效果,根本不需要。
[dcc32 Error] Unit1.pas(33): E2625 Private member 'THideConstructor.Create' is inaccessible here MySingleton.pas(11): Related method: constructor Create;