По целому ряду причин вы не можете достичь именно того, что хотите, но это так близко, как вы можете получить.
Я представил класс «супербаза», если вам нравится со скрытым конструктором, только видимым в этом блоке. Единственная функция TBaseClass теперь состоит в том, чтобы «разоблачить» конструктор, чтобы вы могли создавать экземпляры TBaseClass.
unit Test1;
interface
type
TBaseBaseClass = class
// This does all the work of TBaseClass, but hides the contructor
private
constructor Create; reintroduce; // this can only be accessed within this unit
end;
TBaseClass = class(TBaseBaseClass)
// a creatable class. No actual work is done here. It's only purpose is to
// 'expose' the base constructor
public
constructor Create; reintroduce;
end;
TStringStuff = class( TBaseBaseClass )
public
constructor Create; reintroduce; overload;
constructor Create( str : string ); reintroduce; overload;
end;
TNumStuff = class( TBaseBaseClass )
public
constructor Create( num : integer ); reintroduce; overload;
constructor Create( num : single ); reintroduce; overload;
end;
implementation
{ TStringStuff }
constructor TStringStuff.Create(str: string);
begin
inherited Create;
// ...
// other stuff
end;
constructor TStringStuff.Create;
begin
inherited Create;
// does no extra work! 'exposes' TBaseBaseClass constructor
// but required because of rules of polymorphism
end;
{ TBaseBaseClass }
constructor TBaseBaseClass.Create;
begin
inherited Create;
// ...
// other stuff - does the work originally in TBaseClass
end;
{ TBaseClass }
constructor TBaseClass.Create;
begin
inherited Create;
// does no extra work! 'exposes' TBaseBaseClass constructor
end;
{ TNumStuff }
constructor TNumStuff.Create(num: single);
begin
inherited Create;
// ...
// other stuff
end;
constructor TNumStuff.Create(num: integer);
begin
inherited Create;
// ...
// other stuff
end;
end.
В другом блоке, если вы выполните процедуру тестирования, подобную этой
procedure Test;
var
iBaseClass : TBaseClass;
iStringStuff : TStringStuff;
iNumStuff : TNumStuff;
begin
iBaseClass := TBaseClass.Create;
iStringStuff := TStringStuff.Create;
iNumStuff := TNumStuff.Create;
end;
вы обнаружите, что он не компилируется.
Но есть пара «ошибок». Если вы попытаетесь поместить эту процедуру в ту же единицу, что и исходные определения, она будет скомпилирована. Это связано с тем, что конструктор TBaseBase виден внутри устройства.
Вторая информация связана с тем, что скрытый конструктор не имеет параметров, и существует открытый безпараметрический конструктор для TObject, из которого все объекты спускаются. Поэтому, если вы попытаетесь создать экземпляр TBaseBaseClass, используя конструктор без параметров, он будет компилироваться. Он просто не будет использовать конструктор, которого вы могли бы ожидать. Он будет использовать конструктор TObject.
Наконец, я бы посоветовал никогда не пытаться подсунуть другим программистам. Во что бы то ни стало ведите их в правильном направлении, но не пытайтесь остановить их, делая то, что они хотят делать. Имея это в виду, я бы так не сделал. Я бы сделал конструктор TBaseBase защищенным, а не частным. Я просто показываю это, чтобы ответить на ваш вопрос.