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;