Тема: Abstract Error
Показать сообщение отдельно
  #1  
Старый 10.03.2013, 19:40
Аватар для BBBCat
BBBCat BBBCat вне форума
Новичок
 
Регистрация: 10.03.2013
Сообщения: 73
Репутация: 10
По умолчанию Abstract Error

Всем доброго времени суток!
Вот такая вот программа выдаёт "Abstract Error":

1.Модуль с наследником класса (DescentUnit.pas):
Код:
type
  TDescendantWriter = class(TAscendantWriter)
  public
    function WriteToDoHeader(AHeader: THeader): Boolean; virtual;
  end; // TDescendantWriter = class(TAscendantWriter)

type
  TDescendant = class(TAscendant)
  public
    function StartWrite(AStream: TFileStream): Boolean;
  end; // TDescendant = class(TAscendant)
      
implementation

{ TDescendantWriter }

function TDescendantWriter.WriteToDoHeader(AHeader: THeader): Boolean;
begin
  try
    Write(AHeader, SizeOf(THeader));
    Result := True;
  except
    Result := False;
  end; // try
end; // function TDescendantWriter.WriteToDoHeader(AHeader: THeader): Boolean

{ TDescendant }

function TDescendant.StartWrite(AStream: TFileStream): Boolean;
begin
  Result := inherited StartWrite(AStream, TDescendantWriter);
end; // function TDescendant.StartWrite(AStream: TFileStream): Boolean
2.Модуль с предком класса (AscentUnit.pas):
Код:
type
  THeader = packed record
    A, B: Word;
  end; // THeader = packed record 

  TAscendantWriter = class(TWriter)
  private
    function WriteToDoHeader(AHeader: THeader): Boolean; virtual; abstract;
  end; // TAscendantWriter = class(TWriter)
  TWriterClass = class of TAscendantWriter;

  TAscendant = class(TObject)
  protected
    FFiler: TFiler;
    FFilerClass: TWriterClass;
    FHeader: THeader;

    function WriteHeader: Boolean;

    property Filer: TFiler read FFiler;
    property WriterClass: TWriterClass read FFilerClass;
  public
    function StartWrite(AStream: TStream;
      AWriterClass: TWriterClass): Boolean;
  end; // TAscendant = class(TObject)
      

implementation

{ TAscendant }

function TAscendant.StartWrite(AStream: TStream;
  AWriterClass: TWriterClass): Boolean;
begin
  try
    FFilerClass := AWriterClass;
    FFiler := WriterClass.Create(AStream, 16384);
    Result := WriteHeader;
  except
    Result := False;
  end; // try
end; // function TAscendant.StartWrite(AStream: TStream;
     //   AWriterClass: TCatToDoBasicWriterClass): Boolean

function TAscendant.WriteHeader: Boolean;
begin
  Result := (Filer <> nil) and
            (Filer as WriterClass).WriteToDoHeader(FHeader); // место
                                                             // возникновения
                                                             // ошибки
end; // function TAscendant.WriteHeader: Boolean
Понятно, что обращение происходит к методу из AscentUnit.pas - TAscendantWriter.WriteToDoHeader(AHeader: THeader): Boolean; virtual; abstract;
Как сделать так, чтобы вызывылся метод из DescentUnit.pas - TDescendantWriter.WriteToDoHeader(AHeader: THeader): Boolean; virtual; ?
Реально наследников у абстрактного класса несколько, выбирать нужный необходимо в runtime, поэтому жёстко прописать в программе конкретный нельзя. Разумеется приведённая здесь версия кода сильно упрощённая, реально в классе-предке прописано много чего, поэтому дублировать всё это в наследниках не хочется. Может вместо
(Filer as WriterClass).WriteToDoHeader(FHeader) написать как-то по-другому? Или в объявлении методов что-то подкорректировать? Полностью проект прилагается в заархивированном виде.
Помогите пожалуйста!
Ответить с цитированием