Форум: "Основная";
Текущий архив: 2004.03.28;
Скачать: [xml.tar.bz2];
Вниз
Продолжаю дискуссию о virtual; abstract; Найти похожие ветки
← →
BPK (2004-03-10 09:18) [0]Внимание! дискутируется только то, что написано после "линии отреза".
Тут некоторые участники говорили (http://delphimaster.net/view/1-1078831472/) о бессмысленности связки "virtual; abstract;" и отсылали за примерами в модуль Classes.
Но именно в этом модуле как раз очень часто встречается определение методов со словами virtual; abstract;
Пример: TStrings.Get
function Get(Index: Integer): string; virtual; abstract;
Кроме того, они вещали о том, что такие методы бессмысленно перекрывать с override;
Смотрим тут же - в Classes:
TStringList = class(TStrings)
protected
function Get(Index: Integer): string; override;
Это было написано в защиту моих слов.
===============
А теперь ещё раз говорю о том, что меня волнует:
Я не раз слышал, что полиморфизм метода это разное поведение в сочетании с разными входными/выходными данными, но, как вижу, везде в VCL ни разу речь не заходит о разных данных на входе/выходе процедуры или функции.
Взять хотя бы два вышеупомянутых метода:
function Get(Index: Integer): string; virtual; abstract;
function Get(Index: Integer): string; override;
Здесь мы видим, что поведение метода, наверное, изменилось, но ДАННЫЕ-ТО ПЕРЕДАЮТСЯ ВСЁ ТЕ ЖЕ! Набор входных и выходных данных не менялся!
А мне как раз нужно, чтобы менялся.
Если полиморфизм для этого не подходит, тогда подскажите, как быть.
← →
Anatoly Podgoretsky © (2004-03-10 09:28) [1]Подходит overload, весь полиморфизм побоку и виртуальночсть тоже, в определенной мере.
← →
Внук © (2004-03-10 09:50) [2]>>Тут некоторые участники говорили о бессмысленности >>связки "virtual; abstract;" и отсылали за примерами в модуль >>Classes. Кроме того, они вещали о том, что такие методы >>бессмысленно перекрывать с override;
Не слушай их больше :))
← →
PVOzerski © (2004-03-10 10:10) [3]Дык ведь на то и наследование, и виртуальные методы, чтобы ты взял экземпляр класса как "черный ящик", стандартным образом положил в него данные и стандартным же образом получил результат их обработки, не задумываясь о начинке этого "черного ящика". А вот если данные другие, то такой подход не проходит: не те дырки в ящике :^). Касательно overload: здесь, конечно, мое IMHO, но оно в том, что эта фича вообще мало что дает. Мне никаких удобств не прибавит возможность написать proc("1");proc(1) вместо procStr("1");procInt(1); Разве что если я начну мудрить с include-файлами и изображать что-то вроде шаблонов. Тогда уж уместно говорить о передаче нетипизированных параметров с отдельным указанием, какой же все-таки тип передан. Простейший вариант: type tType=(ttString,ttInteger);procedure proc(var param;kind:tType); развитие этого подхода - variant и array of const. Однако расплачиваться за это придется, как минимум, написанием или использованием мини-интерпретатора (пусть даже в виде оператора case).
← →
BPK (2004-03-10 10:10) [4]Есть решение!
Ключ к решению - директива reintroduce
← →
PVOzerski © (2004-03-10 10:12) [5]Это решение всего лишь подавляет warning.
← →
Reindeer Moss Eater © (2004-03-10 10:13) [6]директива reintroduce - способ избавиться от варнингов компилятора про то, что в наследнике объявлен одноименный метод скрывающий метод предка.
И ничего более.
Никакой это не ключ ни к какому решению
← →
Гаврила (2004-03-10 10:31) [7]Полиморфизм - это если мы работаетм с переменной типа первого предка, не знаем, что там реально создан за потомок, и соответственно передаем тот тип данных, который подходит для методов любого потомка. И получаем разную функциональность в зависимости от реально созданного класса
Если бы в потомках те же методы принимали разыные типы данных, мы должны были бы знать при работе с предком, какой там именно потомок создан, и какой тип данных ему передавать.
То есть мы можем сразу работать с переменной типа потомка, и весь полиморфизм теряет смысл
Это все го лишь пример.
Кстати, а какая задача стоит ?
← →
Reindeer Moss Eater © (2004-03-10 10:36) [8]И получаем разную функциональность в зависимости от реально созданного класса
Только если вызываемый метод - виртуальный.
Если метод статический - диспетчеризацией занимается сам компилятор на основании типа переменной, а не типа созданного экземпляра, который будет в нех храниться
← →
BPK (2004-03-10 10:38) [9]В общем, пришлось отказаться от объявления разномордных методов, а заодно и "property Items" в классе-предке. А жаль.
← →
Гаврила (2004-03-10 10:38) [10]>>>Reindeer Moss Eater © (10.03.04 10:36) [8]
Ну так мы вроде как именно о виртуальных говорим :-)
← →
Vuk © (2004-03-10 10:45) [11]to BPK:
>Я не раз слышал, что полиморфизм метода это разное поведение
>в сочетании с разными входными/выходными данными
Ошибка выделена шрифтом. Слухи врут. Полиморфизм предполагает различную реализацию одного и того же метода разными классами. А что такое один и тот же метод, думаю, объяснять не надо.
← →
icWasya © (2004-03-10 10:48) [12]Есть правда ещё TCollection и TCollectionItem из модуля Classes. Может они частично снимут проблему?
← →
vl_chel © (2004-03-10 11:41) [13]Замечание 1 - абстрактный метод НЕ МОЖЕТ быть статическим, т.е. писать можно только
имя_метода; virtual; abstrаct;
смысл абстрактного метода в том, что он не требует определения (разработки его действий)в данном класе. Это применяется тогда, когда мы работаем с абстрактным объектом и не можем описать его поведение, их разрабатывают в наследнике (с директивой override - переопределенный). Следует помнить, что экземпляры классов содержащих абстрактные методы сильно не рекомендуется создавать.
В твоем примере функции
function Get(Index: Integer): string; virtual; abstract;
function Get(Index: Integer): string; override;
не могут находиться в одном классе
Совет лучше воспользоваться интерфейсами сложнее в разработке но намного гибче в использовании
← →
Тимохов © (2004-03-10 12:15) [14]Я помню эту вчерашнюю дисскуссию.
Автору очень хочется в потомках у методов, определенных в предке, делать параметры разных типов.
Один из моих советов был - используйте pointer. Мой совет поддерживает PVOzerski © (10.03.04 10:10) [3] - прелагает пользоваться теми же pointer, только не явно, через нетипизированный параметр.
Автору, лично: вообще, интересное дело получается - вас многократно спрашивали что вы вообще добиваетесь. Вы про ваши задачи не говорите совсем. Может скажете? Тогда и способов решения можно много подыскать. :)))
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.03.28;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.042 c