Как получить доступ к функциям в дочерних классах? - PullRequest
1 голос
/ 20 июля 2009

Дочерний класс может получить доступ к защищенным функциям в родительском классе, но родительский класс не может получить доступ к защищенным функциям в дочернем классе.

Я бы хотел сохранить оба класса настолько закрытыми, насколько это возможно. Родительский класс является формой и используется только один раз. Все функции в дочернем классе являются статическими, он наследуется от родительского класса.

Как можно получить доступ к непубличным статическим методам в дочернем классе ( в другом модуле ) из родительского класса?

EDIT:

Родительский класс (Первый блок):

interface

type
TParent = class
  public
    procedure Initialize;
  protected
    procedure Test; virtual;
end;

implementation

procedure TParent.Initialize;
begin
  Writeln('Initializing');
  Test;
end;

procedure TParent.Test;
begin

end;

Детский класс (Второй блок):

interface

uses
ParentClass;

type
TChild = class(TParent)
protected
  procedure Test;override;
end;

implementation

procedure TChild.Test;
begin
  Writeln('Test!');
end;

Код (третье устройство):

var c:TParent;

begin
  try
    c := c.Create;
    c.Initialize;
    c.Free;
    Readln;
end;

Вывод только "инициализируется". Я пытался отладить его, он не достигает дочернего класса.

Ответы [ 5 ]

3 голосов
/ 20 июля 2009

Есть несколько способов сделать это в вашем родительском классе, создать виртуальные методы, которые вы вызываете, но они ничего не делают. В ваших дочерних классах переопределите эти методы. Методы могут быть легко защищены, но они должны существовать в родительском.

type
  TParent = class
  protected
    procedure SpecialProcessing; virtual;
  public
    procedure DoWork;
  end;

  TChild = class(TParent)
  protected
    procedure SpecialProcessing; override;
  end;

procedure TParent.DoWork;
begin
  SpecialProcessing;
end;

procedure TParent.SpecialProcessing;
begin
  // does nothing, placeholder
end;

procedure TChild.SpecialProcessing;
begin
  // do special work here
end;

Я специально НЕ делал абстрактную обработку TParent.Speciall. Это может быть сделано, но только если TParent никогда не будет создан напрямую, будут только потомки. Абстрактный метод - это метод, который НЕ реализован, но используется в качестве заполнителя для реализации более поздним дочерним элементом.

Для создания экземпляра вы используете следующее:

var
  C : TParent;
begin
  // Create as a TChild, which is a TParent decendant
  C := TChild.Create;
  try
    C.DoWork;
  finally
    C.Free;
  end;
end;
3 голосов
/ 20 июля 2009

То, что вы хотите сделать, нарушает принцип подстановки Лискова в наследовании. Вероятно, есть лучший способ сделать это. Что именно вы хотите сделать?

EDIT:

Почему вы не можете создать экземпляр объекта из дочернего класса. Вы всегда можете присвоить его переменной типа родительского класса. Обычно это делается по заводским образцам.

2 голосов
/ 20 июля 2009

Это невозможно сделать. Вся цель наличия непубличных методов в дочернем классе состоит в том, чтобы предотвратить доступ к ним классов (кроме дочернего класса). Попытка обойти это нарушает основные объектно-ориентированные принципы.

Я бы подумал переосмыслить твой дизайн.

1 голос
/ 20 июля 2009

Я мог бы упустить что-то очевидное для людей, которые уже ответили. Но я думаю, что это просто вопрос создания правильного объекта.

Родительский код будет вызывать дочерний код, если объект является экземпляром дочернего класса.

Попробуйте это

var c:TChild;
begin
  c := TChild.Create;
  c.Initialize;
  c.Free;
end.

или даже

var c:TParent;
begin
  c := TChild.Create;
  c.Initialize;
  c.Free;
end.
0 голосов
/ 20 июля 2009

Вы можете сделать это, зарегистрировав дочерний класс с родителем при его создании, используя какой-то обратный вызов (cattr для родителя, и дочерний объект устанавливается, когда он определен).

Хотя это редко бывает правильно. Как уже говорили другие, рассмотрим другой шаблон.

Я не кодер delphi, но вы можете установить открытую статическую переменную для родительского класса и установить ее из метода установки в дочернем классе.

Это имеет смысл в некоторых ситуациях (желая передать сообщения в методы настройки класса на различных дочерних классах), но, вероятно, есть лучший способ сделать то, что вам нужно. Возможно, вы захотите задать свой вопрос о проблеме, которую решает ваш код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...