Помощь - Поиск - Пользователи - Календарь
Полная версия: Перекрывание методов...
Форум «Всё о Паскале» > Современный Паскаль и другие языки > Делфи
Vardes
Всё ещё пытаюсь разобраться с Delphi,поэтому такой вам вопрос...Что означает перекрывание методов с помощью override,зачем это нужно,если мы можем просто в потомке создать одноимённый метод с другими пар-ми,и просто его запустить...?
volvo
Цитата
если мы можем просто в потомке создать одноимённый метод с другими пар-ми, и просто его запустить...?
А если НЕ в потомке, а в том же классе мне понадобится создать 2 метода с одинаковым именем, но разными параметрами, тогда как без Override?
Vardes
А можно на это пример привести?
volvo
А попробуй откомпилировать:
...
b = object
float_add: double;
procedure print(i: integer);
procedure print(f: double); // <--- Ошибочка, Override надо !!!

end;

procedure b.X(f: double);
begin
showmessage(floattostr(f + float_add));
end;
procedure b.X(i: integer);
begin
showmessage(inttostr(i));
end;
...
Только не спрашивай, зачем ЭТО нужно... Вот нужно мне это и все... Я не хочу запоминать десять имен типа print_integer/print_double/print_string/print_char ..., а хочу использовать перегрузку и работать с print, а что именно должно быть вызвано - это пусть компилятор разбирается...
Vardes
А если я сделаю вот так:
Код

type
TD1 = class(Tobject)
x1:integer;
procedure Do(x1:integer);
end;
TD2 = class(T1)
x2:integer;
procedure Do(x2:integer);
var
...........
procedure TD1.Do(x1:integer)
begin
x1:=X1*X1;
end;
procedure TD2.Do(x2:integer)
begin
x2:=X2/X2;
end;
............
D1.Do;
D2.Do;

метод потомка автоматически перекроет метод предка без всякого override?
volvo
А с НЕвиртуальными методами вообще не используется Override... Я там выше ошибся кстати, надо не Override, а Overload добавлять...

А по поводу разницы между методом С override и БЕЗ него - написано в хелпе:
Цитата(D6 Help)
Overriding versus hiding
If a method declaration specifies the same method identifier and parameter signature as an inherited method, but doesn’t include override, the new declaration merely hides the inherited one without overriding it. Both methods exist in the descendant class, where the method name is statically bound.
Вот тебе и разница...
мисс_граффити
Попробуй запустить две программки:

1.
TA=class
a,b,c:integer;
procedure first;
procedure second;virtual;
end;

TB=class(TA)
procedure second;override;
end;
....
procedure TA.second;
begin
c:=a+b;
end;

procedure TA.first;
begin
a:=5;
b:=8;
second;
end;

procedure TB.second;
begin
c:=a-b;
end;

procedure TForm1.Button1Click(Sender: TObject);
var O2: TB;
begin
O2:=TB.Create;
O2.first;
ShowMessage(IntToStr(O2.c));
end;



2.
TA=class
a,b,c:integer;
procedure first;
procedure second;
end;

TB=class(TA)
procedure second;
end;
....
procedure TA.second;
begin
c:=a+b;
end;

procedure TA.first;
begin
a:=5;
b:=8;
second;
end;

procedure TB.second;
begin
c:=a-b;
end;

procedure TForm1.Button1Click(Sender: TObject);
var O2: TB;
begin
O2:=TB.Create;
O2.first;
ShowMessage(IntToStr(O2.c));
end;


Я думаю, разницу увидишь.

Цитата
А с НЕвиртуальными методами вообще не используется Override...

Динамический рассматривается как разновидность виртуального? А то я всегда мучаюсь - как бы их одним словом обозвать.
volvo
Цитата
Динамический рассматривается как разновидность виртуального?
Это фактически одно и то же:
Цитата(D6 Help)
Virtual versus dynamic
Virtual and dynamic methods are semantically equivalent. They differ only in the implementation of method-call dispatching at runtime. Virtual methods optimize for speed, while dynamic methods optimize for code size.
мисс_граффити
но ведь:
Цитата
Virtual methods optimize for speed, while dynamic methods optimize for code size.

достигается за счет разной реализации? то есть это по сути разные вещи...
а обобщающего слова не придумали sad.gif
volvo
Юля, кстати... Вопрос на засыпку: что будет выведено в результате выполнения следующего кода:
uses sysutils;

type
TA = class
a,b,c:integer;
procedure first;
procedure second; virtual;
end;

TB = class(TA)
procedure second; virtual;
end;

procedure TA.second;
begin
c := a+b;
end;

procedure TA.first;
begin
a := 5;
b := 8;
second;
end;

procedure TB.second;
begin
c:=a-b;
end;

var O2: TB;
begin
O2:=TB.Create;
O2.first;
writeln(IntToStr(O2.c));
end.
(НЕ override !!! Виртуальные функции... ) Если можно - без использования компилятора, что ТЕОРЕТИЧЕСКИ должно быть выведено? smile.gif ...
Bokul
Цитата
Вопрос на засыпку: что будет выведено в результате выполнения следующего кода:

Спойлер (Показать/Скрыть)

мисс_граффити
в таком виде - ошибка ;)
а по сути - раз override нет, то, думаю, 13... то есть вызовется first от TA
volvo
smile.gif
Еще варианты будут?

Кстати, дополнение к вопросу: как изменится картина (если изменится), если я опишу first вот так:
type
TA = class
a,b,c:integer;
procedure first; virtual; // <-- !!!
procedure second; virtual;
end;
cool.gif

Цитата
в таком виде - ошибка ;)
С чего бы? Нет тут никакой ошибки smile.gif Все работает... Вопрос в силе...
мисс_граффити
а... сорри. про консольные приложения забыла.

мне кажется, не изменится никак.


volvo
Хорошо, допустим... А теперь - контрольный выстрел: smile.gif

Что будет сейчас?

uses sysutils;

type
TA = object
a,b,c:integer;
constructor create;
procedure first;
procedure second; virtual;
end;

TB = object(ta)
constructor create;
procedure second; virtual;
end;

constructor ta.create;
begin end;
procedure TA.second;
begin
c := a+b;
end;


procedure TA.first;
begin
a := 5;
b := 8;
second;
end;

constructor tb.create;
begin inherited create; end;
procedure TB.second;
begin
c:=a-b;
end;

var O2: TB;
begin
o2.create;
O2.first;
writeln(IntToStr(O2.c));
end.

blum.gif
мисс_граффити
по-моему, даже такое изменение в коде:
constructor tb.create;
begin end;

ни на что не повлияет.
а выдаст она -3.
пояснения написать?
volvo
Да... Вот теперь меня и интересуют пояснения, ПОЧЕМУ один и тот же код по-твоему при использовании классов выдаст одно, а при использовании объектов - другое... Объяснение этому факту приведи, пожалуйста... (я надеюсь это не "проверено на компиляторе"? Меня интересует логика...)
Vardes
Ух ты!!!!
Какое здесь обсуждение завели,спасибо вам...теперь хоть стал немного разбираться...Но возникли ещё вопросы по поводу визуальных компонент....
Есть такой класс в Delphi,как TStaticText,я его использую,для просмотра значения переменной в цикле (цикл большой,от 1000),ну так вот,где-то первые значения мне строка показывает,а потом переменные перестают выводиться на экран в течение цикла, как только он заканчивается выводится последний результат.Из-за чего такое может быть?И ещё....никак не могу понять как работать с классом TspinEdit...могли бы вы привести пример для задания значения переменной?Заранее спасибо smile.gif
мисс_граффити
по-моему, после такой дискуссии начать разбираться нереально. smile.gif
volvo, в общем это.... знаний немного, так что на 90% собственное домысливание (с применением женской логики). соответственно, могу ошибаться...
отталкивалась от того, что object есть и в паскале, а class - только в делфи. (коряво по терминологии, понимаю, что глупо сравнивать язык и среду... но, думаю, идею уловил).
object оставили, как мне кажется, для совместимости...
а раз для совместимости - значит, работать они должны по тому же принципу, что и в паскале (а иначе какой смысл?). что такое override паскаль не знает, а что такое virtual - прекрасно понимает. поскольку у нас есть конструктор (хоть и пустой, на первый взгляд ничего не делающий) - таблица вирт.методов создается как положено. итак, раз virtual, надо использовать метод потомка.
теперь пример с классами. делфи про override прекрасно знает. а раз его нет - значит, и перекрывания не происходит (а чего перекрывать, если не просят?)...

Vardes, по второму вопросу:
a:integer;
...
a:=SpinEdit1.Value;
Vardes
Хотелось бы ещё узнать про TStaticTest...как можно увеличить в этом классе дину строки,а то показывает мне только 14 знаков после запятой (у меня так переменная меняется),а надо больше)
мисс_граффити
Vardes, а почему тебе нужен именно этот компонент?
и в чем проблема - в знаках после запятой или в не выводящихся разных значениях?
вообще, покажи кусок кода, где эти вычисления идут.
с типами данных, которые используешь.
Vardes
Просто этот компонент показывает изменение переменной....но мне необходимо,чтоб он показывал больше знаков после запятой,а не 14,т.к. переменная изменяется мало
Код


var
err:extended; //значение переменной (моей функции)
.................
procedure TA1.error(err:extended) // процедура по вычислению функции
.............
for i:=1 to 10000 do begin
A1.error(err:extended);
StaticText1.Caption:=FloatToStr(err); //вывод значения на экран
end;
volvo
Vardes, а знаешь, почему?
Цитата(D6 Help)
FloatToStr function
FloatToStr converts the floating-point value given by Value to its string representation. The conversion uses general number format with 15 significant digits.

For greater control over the formatting of the string, use the FloatToStrF function.

Так что FloatToStrF тебе в помощь, она даст точность до 18-го знака после запятой... А больше и не получится, т.к. у Extended максимальная точность 19-20 знаков
Vardes
Понял,что FloatToStrF тоже мне не поможет,может у кого-нить есть пример функции по переводу из действительного типа в строковый?НУ самодельная... cool.gif
volvo
StaticText1.Caption:=FloatToStr(err, ffFixed, 18, 18);

тоже не получается? Неужели трудно F1 нажать?
Vardes
Да меня сначала на форум тянет,а потом я в справку лезу и нахожу там ответы на свои вопросы,так противно за себя становится,я буду пытаться исправится.
FloatToStrF,тоже не подойдёт...после запятой надо ещё больше цифр,ну да и хрен с ним...обойдусь как-нить,буду надеяться,что значение функции будет выше,а не стремится к 0)
мисс_граффити
ну, больше их не станет независимо от метода перевода.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.