Проблема с ООП, Баг с наследованием. |
1. Заголовок или название темы должно быть информативным !
2. Все тексты фрагментов программ должны помещаться в теги [code] ... [/code] или [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ" и используйте ПОИСК !
4. НЕ используйте форум для личного общения!
5. Самое главное - это раздел теоретический, т.е. никаких задач и программ (за исключением небольших фрагментов) - для этого есть отдельный раздел!
Проблема с ООП, Баг с наследованием. |
LHx |
Сообщение
#1
|
Новичок Группа: Пользователи Сообщений: 11 Пол: Мужской Репутация: 0 |
В общем, поясняю. У меня есть объект obj, содержащий метод move, который, в свою очередь, использует метод collide. От obj происходит объ. dot, тоже использующий НЕизмененный метод move, который _должен_ использовать измененный метод dot.collide, однако использует метод obj.collide. Видимо, для использования метода dot.c..... придется перекрывать метод move, а это долго. Есть методы без извращений?
-------------------- Если отладка - процесс удаления ошибок из программы, то программирование должно быть процессом их внесения.
|
BlackShadow |
Сообщение
#2
|
Гость |
Конструктор - штука интересная. По сути это процедура, которая вызывается не ПРИ создании, а ДЛЯ создания объекта. Он имеет Параметр №0 и строчку №0. Параметр №0, это как в любом другом методе - Self, то есть ссылка на экземпляр класса, вызвавшего метод. Сточка №0 куда интереснее. Она проверяет Self на Nil. Если это так, то объект располагается в динамической памяти. В таком случае нужно ему её выделить, что конструктор и делает. Затем смотрит, имеет ли этот класс виртуальные методы. Если имеет, то заполняет его поле VMT (поле №0 ) адресом VMT Этого класса. Затем уж происходит вызов того, что ты сам насочинял. Параметр Self к этому времени имеет уже корректное значение.
Мало того конструктор - единственная функция, которая может быть вызвана без сохранения результатов при любой настройки компилятора. Да-да, именно функция. И та необычная. Её результат можно использовать как Boolean (для проверки вызова Fail в теле конструктора), как Pointer, чтобы узнать где расположился твой объект, и как указатель на экземпляр какого-то там класса. Деструктор - штука более банальная. Он вызывается ПРИ уничтожении объекта и служит как правило для освобождения ресурсов занятых под нужды объекта. Например для класса списка, логично освобождать в нём память, а для файла - закрывать его. Виртуальные функции - основа ООП. Вот тебе пример из ЛЮБОЙ книжки по паскалю, где вообще этот вопрос задевается: Код Uses Graph,CRT; Type TFigure=Object x:Integer; y:Integer; Constructor Create(ax,ay:Integer); Procedure Draw;Virtual; Destructor Destroy;Virtual; End; TRound=Object(TFigure) r:Integer; Constructor Create(ax,ay,ar:Integer); Procedure Draw;Virtual; Destructor Destroy;Virtual; End; TRect=Object(TFigure) a:Integer; b:Integer; Constructor Create(ax,ay,aa,ab:Integer); Procedure Draw;Virtual; Destructor Destroy;Virtual; End; Constructor TFigure.Create(ax,ay:Integer); Begin x:=ax; y:=ay End; Procedure TFigure.Draw; Begin End; Destructor TFigure.Destroy; Begin End; Constructor TRound.Create(ax,ay,ar:Integer); Begin Inherited Create(ax,ay); r:=ar End; Procedure TRound.Draw; Begin SetColor(Red); Circle(x,y,r) End; Destructor TRound.Destroy; Begin SetColor(Black); Circle(x,y,r) End; Constructor TRect.Create(ax,ay,aa,ab:Integer); Begin Inherited Create(ax,ay); a:=aa; b:=ab End; Procedure TRect.Draw; Begin SetColor(Red); Rect(x,y,x+a,x+b) End; Destructor TRect.Destroy; Begin SetColor(Black); Rect(x,y,x+a,x+b) End; Var a:Array[0..99] Of ^TFigure; i:Integer; Begin {InitGraph там какой-нибудь...} For i:=Lo(a) To Hi(a) Do If Random(2)=1 Then a[i]:=New(TRound,Create(Random(GetMaxX),Random(GetMaxY),Random(100)) Else a[i]:=New(TRect,Create(Random(GetMaxX),Random(GetMaxY),Random(100),Random(100)); For i:=Lo(a) To Hi(a) Do a[i]^.Draw; ReadKey; For i:=Lo(a) To Hi(a) Do Dispose(a[i],Destroy); ReadKey; RestoreCRTMode End. Уф... Запарился пока писал. Попробуй разберись сам - тут всё примитивно. Если что - спрашивай. Суть виртуальных примерно такая - они могут заменять или дополнять функции предков. В этом примере конструктор (он всегда типа виртуальный) дополняет метод предка, а процедура Draw - заменяет. З. Ы. : а вообще, Oleg_Z писал введение в ООП и закреплял его, по-моему. Там-то должно быть про это всё рассказано. |
Текстовая версия | 19.05.2024 4:17 |