Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Abstract Error в родительском классе, Abstract Error 
V
    Опции темы
Keeper89
Дата 13.10.2009, 14:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2580
Регистрация: 26.2.2009

Репутация: 20
Всего: 58



Доброго времени суток.

Имеется 4 класса:
Код

- A
-- B
----B1
----B2
-- C

Т.е. родительский A, имеет 2 дочерних B и С, а B в свою очередь имеет свои 2 дочерних.

В A имеется следующий абстрактный метод:
Код

function Valid(const Name, Path: AnsiString;
                      var mes: AnsiString): Boolean; virtual; abstract;

реализуемый только в B1, B2 и C, в B он остается абстрактным для реализации в дочерних классах.

---

Проблема в следующем. Класс A содержит процедуру:
Код

procedure A.Add(const Name, Path: AnsiString);
begin
  // Добавляем закладку

  if Valid(Name, Path, mes) then
    ...
end;

который ссылается на реализованный Valid в потомках.
При попытке добавить записать (вызвать Add) у классов B1, B2 выскакивает EAbstractError, хотя в B1 и B2 метод Valid имеется.

---

Вот, в чем может быть ошибка? 


--------------------
PM MAIL WWW   Вверх
CodeMonkey
Дата 13.10.2009, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 38
Всего: 89



Забыли override?


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Keeper89
Дата 13.10.2009, 15:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2580
Регистрация: 26.2.2009

Репутация: 20
Всего: 58



в B1, B2 и C override стоит:
Код

function Valid(const Name, Path: AnsiString;
                     var mes: AnsiString): Boolean; override;

в B объявление такое же как и в A.

Это сообщение отредактировал(а) Keeper89 - 13.10.2009, 15:57


--------------------
PM MAIL WWW   Вверх
CodeMonkey
Дата 13.10.2009, 16:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 38
Всего: 89



Возможно криво создали класс. 
Конструктор виртуальный?


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
bems
Дата 13.10.2009, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 31
Всего: 88



Присоединяюсь. Похоже что создан экземпляр с абстрактным методом.


--------------------
Обижено школьников: 8
PM MAIL   Вверх
Keeper89
Дата 13.10.2009, 22:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2580
Регистрация: 26.2.2009

Репутация: 20
Всего: 58



CodeMonkey
bems
если я правильно понял - как раз это я и сделал.

Классы по очереди:

A:
Код

  A = class(TObject)
    protected
      function Valid(const Name, Path: AnsiString;
                     var mes: AnsiString): Boolean; virtual; abstract;
    public
      constructor Create();
      procedure Add(const Name, Path: AnsiString);
  end;


B:
Код

  B = class(A)
    public
      constructor Create(); overload;
      constructor Create(fsFavsCur: TNonSysFavorites); overload;
      constructor Create(lvFavs: TListView;
                         editMode: Boolean = False); overload;
      procedure Assign(fsFavsCur: TNonSysFavorites); overload;
      procedure Assign(lvFavs: TListView;
                       editMode: Boolean = False); overload;
      function Valid(const Name, Path: AnsiString;
                     var mes: AnsiString): Boolean; virtual; abstract;
  end;


B1,B2:
Код

  B1 = class(B)
    public
      function Valid(const Name, Path: AnsiString;
               var mes: AnsiString): Boolean; override;
  end;


C:
Код

  C = class(A)
    public
      constructor Create();
      function Valid(const Name, Path: AnsiString;
               var mes: AnsiString): Boolean; override;
  end;


Это сообщение отредактировал(а) Keeper89 - 13.10.2009, 22:42


--------------------
PM MAIL WWW   Вверх
bems
Дата 13.10.2009, 22:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 31
Всего: 88



ааа.
Так у тебя B.Valid скрывает A.Valid.
В В1 и В2 ты перекрываешь скрывающий из B, а самый первый из А так и остается абстрактным. И он же вызывается. 
Ты что хотел этим добиться? Если я правильно понял, нужно убрать объявление из В


--------------------
Обижено школьников: 8
PM MAIL   Вверх
Keeper89
Дата 13.10.2009, 23:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2580
Регистрация: 26.2.2009

Репутация: 20
Всего: 58



Цитата(bems @  13.10.2009,  23:53 Найти цитируемый пост)
Ты что хотел этим добиться?

В каждом дочернем классе я хотел сделать свой метод проверки Valid (в B1, B2 и C), в родителях же он просто декларируется.

В этом случае просто убрать абстрактное объявление Valid в B? Может можно еще что-то улучшить в структуре классов?

Это сообщение отредактировал(а) Keeper89 - 13.10.2009, 23:21


--------------------
PM MAIL WWW   Вверх
bems
Дата 14.10.2009, 00:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 31
Всего: 88



Цитата(Keeper89 @  13.10.2009,  23:20 Найти цитируемый пост)
В этом случае просто убрать абстрактное объявление Valid в B?
ну да. А разве компилятор ворнинга не выдал?


Цитата(Keeper89 @  13.10.2009,  23:20 Найти цитируемый пост)
Может можно еще что-то улучшить в структуре классов?
ну если у потомков будут добавляться новые свойства то наверное Assign должен тоже быть виртуальным



--------------------
Обижено школьников: 8
PM MAIL   Вверх
Romikgy
Дата 14.10.2009, 10:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 26
Всего: 146



имхо 
Код

B = class(A)
    public
      constructor Create(); overload;
      constructor Create(fsFavsCur: TNonSysFavorites); overload;
      constructor Create(lvFavs: TListView;
                         editMode: Boolean = False); overload;
      procedure Assign(fsFavsCur: TNonSysFavorites); overload;
      procedure Assign(lvFavs: TListView;
                       editMode: Boolean = False); overload;
      function Valid(const Name, Path: AnsiString;
                     var mes: AnsiString): Boolean; overload;
  end;



--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Keeper89
Дата 14.10.2009, 11:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2580
Регистрация: 26.2.2009

Репутация: 20
Всего: 58



bems, все получилось,  спс!

Цитата(bems @  14.10.2009,  01:41 Найти цитируемый пост)
А разве компилятор ворнинга не выдал?

Выдавал, я не заметил: [DCC Warning] W1010 Method 'Valid' hides virtual method of base type 'A'

Цитата(bems @  14.10.2009,  01:41 Найти цитируемый пост)
ну если у потомков будут добавляться новые свойства то наверное Assign должен тоже быть виртуальным

Учту, хотя вряд ли будут еще дочерние классы.

Исходя из исправления вопрос: получается, что виртуально-абстрактный метод реализуется только в последнем дочернем классе, а во всех остальных кроме базового даже не декларируется?


--------------------
PM MAIL WWW   Вверх
bems
Дата 14.10.2009, 16:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 31
Всего: 88



Цитата(Keeper89 @  14.10.2009,  11:03 Найти цитируемый пост)
Выдавал, я не заметил: [DCC Warning] W1010 Method 'Valid' hides virtual method of base type 'A'
Нельзя такого незамечать. Этот ворнинг говорит что ты или должен указать override (это тот же метод) или reintroduce (это новый метод, ты действительно хочешь скрыть унаследованый)

Цитата(Keeper89 @  14.10.2009,  11:03 Найти цитируемый пост)
получается, что виртуально-абстрактный метод реализуется только в последнем дочернем классе, а во всех остальных кроме базового даже не декларируется? 
не обязательно в последнем дочернем. Это значит что после того как ты задекларировал его как абстрактный, новая декларация нужна только там, где ты хочешь его перекрыть (не обязательно в последнем и не обязательно один раз)



--------------------
Обижено школьников: 8
PM MAIL   Вверх
Keeper89
Дата 14.10.2009, 20:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2580
Регистрация: 26.2.2009

Репутация: 20
Всего: 58



bems, ок, спасибо!

З.Ы. Assign пока не менял, в потомках он не переопределяется.

Это сообщение отредактировал(а) Keeper89 - 14.10.2009, 20:55


--------------------
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1119 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.