В общем, поясняю. У меня есть объект obj, содержащий метод move, который, в свою очередь, использует метод collide. От obj происходит объ. dot, тоже использующий НЕизмененный метод move, который _должен_ использовать измененный метод dot.collide, однако использует метод obj.collide. Видимо, для использования метода dot.c..... придется перекрывать метод move, а это долго. Есть методы без извращений?
"Баг с наследованием" - ну это не баг. а чтобы использовать метод предка, используй inherited move. но это, конечно, вызовет и родительский collide.
Проблема решается с полпинка, если сделать метод collide виртуальным.
type
obj = object
...
procedure move;
procedure collide; virtual;
...
end;
dot = object (obj)
...
{ процедуры move нету -- она родительская }
procedure collide; virtual;
...
end;
пробовал виртуальные, дык Паскаль вылетает...
Как это вылетает? Не должен же вроде.
Ну-ка, с этого места поподробнее...
Объясняю популярно.
Во-первых:
Ну тогда конечно... Кто же пишет объектно-ориентированно, но без виртуальных функций и конструкторов/деструкторов? По-моему, уж лучше тогда писать "как на C" -- т.е. без классов и наследования.
Извращенское решение поставленной задачи: заведите себе в классе obj переменную, которая будет показывать, объект ли это типа obj или всё-таки dot. Не забудьте их проинициализировать. В процедуре collide, которая должна быть только у obj, делаем проверку. Если переменная имеет значение 1, выполняем одни действия, если 2, то другие.
Правильное (то есть объектно-ориентированное) решение: использовать виртуальные функции, завести конструктор и деструктор, создавать объект только посредством New, удалять объект после использования посредством Dispose. Научиться работать с указателями (хотя я надеюсь, что это вы знаете).
Могу рассказать поподробнее.
jaros, ну не обязательно лезть в динамическую память. Можно и по-проще. Например, если класс TMyObject имеет конструктор Create и деструктор Destroy, то можно просто и банально:
TypeOf на самом деле возвращает указатель на таблицу виртуальных функций. Если он не проинициализирована конструктором (как у товарища), то typeof должен вернуть чушь. Сравнивать одну чушь с другой и надеяться, что они совпадут или не совпадут именно когда надо, я бы не стал... Но после конструктора всё должно быть в порядке.
Исключение составляет TypeOf(TMyObject), который берёт инфу совсем не из поля VMT
Поясните балде, что значат директивы constructor, destructor и virtual.
грубо говоря ,конструктор -- метод который вызывается при создании объекта ,деструктор -- при уничтожении объекта.
виртуальные методы -- хз.
Конструктор - штука интересная. По сути это процедура, которая вызывается не ПРИ создании, а ДЛЯ создания объекта. Он имеет Параметр №0 и строчку №0. Параметр №0, это как в любом другом методе - Self, то есть ссылка на экземпляр класса, вызвавшего метод. Сточка №0 куда интереснее. Она проверяет Self на Nil. Если это так, то объект располагается в динамической памяти. В таком случае нужно ему её выделить, что конструктор и делает. Затем смотрит, имеет ли этот класс виртуальные методы. Если имеет, то заполняет его поле VMT (поле №0 ) адресом VMT Этого класса. Затем уж происходит вызов того, что ты сам насочинял. Параметр Self к этому времени имеет уже корректное значение.
Мало того конструктор - единственная функция, которая может быть вызвана без сохранения результатов при любой настройки компилятора. Да-да, именно функция. И та необычная. Её результат можно использовать как Boolean (для проверки вызова Fail в теле конструктора), как Pointer, чтобы узнать где расположился твой объект, и как указатель на экземпляр какого-то там класса.
Деструктор - штука более банальная. Он вызывается ПРИ уничтожении объекта и служит как правило для освобождения ресурсов занятых под нужды объекта. Например для класса списка, логично освобождать в нём память, а для файла - закрывать его.
Виртуальные функции - основа ООП. Вот тебе пример из ЛЮБОЙ книжки по паскалю, где вообще этот вопрос задевается:
virtual; - когда нужно перекрыть метод.
Например, есть метод Draw для отрисовки какой-то фигуры.
Если необходимо изменить только отрисовку объекта, то нет нужды писать новый объект, а надо просто "перекрыть" новым методом.
Не обязательно перекрыть! Можно просто дополнить. Например:
Тему в "Теоретические" ?
Согласен. Тут она не в теме
никак не понял где faq. ну ладно.
хочу научиться использовать меню.. паскаль сказал, что есть на этот счет объект TMenuView, но образца не нашел.
и не работал с объектами както раньше.
не напишите коротенький код для простейшего меню?
Не в тему. Создай свой топик в нужном разделе.