![]() |
|
#1
|
||||
|
||||
![]() Всем доброго времени суток!
Вот такая вот программа выдаёт "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 Код:
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 Как сделать так, чтобы вызывылся метод из DescentUnit.pas - TDescendantWriter.WriteToDoHeader(AHeader: THeader): Boolean; virtual; ? Реально наследников у абстрактного класса несколько, выбирать нужный необходимо в runtime, поэтому жёстко прописать в программе конкретный нельзя. Разумеется приведённая здесь версия кода сильно упрощённая, реально в классе-предке прописано много чего, поэтому дублировать всё это в наследниках не хочется. Может вместо (Filer as WriterClass).WriteToDoHeader(FHeader) написать как-то по-другому? Или в объявлении методов что-то подкорректировать? Полностью проект прилагается в заархивированном виде. Помогите пожалуйста! Последний раз редактировалось BBBCat, 12.03.2013 в 18:46. |
#2
|
||||
|
||||
![]() А оверрайдить кто его будет?
— Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию |
#3
|
||||
|
||||
![]() Цитата:
|
#4
|
||||
|
||||
![]() Знаешь как абстрактные методы работают, как их перекрывать и т.д.?
Остальные, не подсказывайте! — Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию Последний раз редактировалось M.A.D.M.A.N., 10.03.2013 в 20:03. |
#5
|
||||
|
||||
![]() Я так понимаю, что они как раз не работают. Существуют для создания скелета с последующим наполнением кодом в наследниках. Что я и пытаюсь сделать. Только вот как-то криво получается
![]() |
#6
|
||||
|
||||
![]() — Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию |
#7
|
||||
|
||||
![]() Спасибо, сейчас почитаю.
|
#8
|
||||
|
||||
![]() M.A.D.M.A.N. В предке убрал abstract, в наследнике добавил override, ошибку больше не выдаёт, спасибо! Но пришлось добавить пустое тело метода раз уж он перестал быть абстрактным. А вот никак нельзя оставить его абстрактным и обойтись без пустой функции?
|
#9
|
||||
|
||||
![]() virtual; abstract; так же override'ом перекрывается. Добавь абстракт и выкинь пустое тело.
Вот видишь, решение очевидное. Опыт +5, знания + 1. — Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию |
Этот пользователь сказал Спасибо M.A.D.M.A.N. за это полезное сообщение: | ||
BBBCat (10.03.2013)
|
#10
|
||||
|
||||
![]() Всё получилось с абстрактным методом, спасибо M.A.D.M.A.N. !!! Но вот хоть убейте, уверен, что так уже пробовал и выдавало ошибку на этапе компиляции(Build All). Видимо глючу...
![]() |