Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Делфи _ Перекрывание методов...

Автор: Vardes 22.11.2006 22:26

Всё ещё пытаюсь разобраться с Delphi,поэтому такой вам вопрос...Что означает перекрывание методов с помощью override,зачем это нужно,если мы можем просто в потомке создать одноимённый метод с другими пар-ми,и просто его запустить...?

Автор: volvo 22.11.2006 22:51

Цитата
если мы можем просто в потомке создать одноимённый метод с другими пар-ми, и просто его запустить...?
А если НЕ в потомке, а в том же классе мне понадобится создать 2 метода с одинаковым именем, но разными параметрами, тогда как без Override?

Автор: Vardes 22.11.2006 22:59

А можно на это пример привести?

Автор: volvo 22.11.2006 23:07

А попробуй откомпилировать:

...
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 23.11.2006 0:26

А если я сделаю вот так:

Код

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 23.11.2006 0:44

А с НЕвиртуальными методами вообще не используется 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.
Вот тебе и разница...

Автор: мисс_граффити 23.11.2006 3:43

Попробуй запустить две программки:

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 23.11.2006 4:06

Цитата
Динамический рассматривается как разновидность виртуального?
Это фактически одно и то же:
Цитата(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.

Автор: мисс_граффити 23.11.2006 4:18

но ведь:

Цитата
Virtual methods optimize for speed, while dynamic methods optimize for code size.

достигается за счет разной реализации? то есть это по сути разные вещи...
а обобщающего слова не придумали sad.gif

Автор: volvo 23.11.2006 4:21

Юля, кстати... Вопрос на засыпку: что будет выведено в результате выполнения следующего кода:

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 23.11.2006 4:32

Цитата
Вопрос на засыпку: что будет выведено в результате выполнения следующего кода:

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


Автор: мисс_граффити 23.11.2006 4:34

в таком виде - ошибка ;)
а по сути - раз override нет, то, думаю, 13... то есть вызовется first от TA

Автор: volvo 23.11.2006 4:36

smile.gif
Еще варианты будут?

Кстати, дополнение к вопросу: как изменится картина (если изменится), если я опишу first вот так:

type
TA = class
a,b,c:integer;
procedure first; virtual; // <-- !!!
procedure second; virtual;
end;
cool.gif

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

Автор: мисс_граффити 23.11.2006 4:58

а... сорри. про консольные приложения забыла.

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



Автор: volvo 23.11.2006 5:01

Хорошо, допустим... А теперь - контрольный выстрел: 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

Автор: мисс_граффити 23.11.2006 5:38

по-моему, даже такое изменение в коде:

constructor tb.create;
begin end;

ни на что не повлияет.
а выдаст она -3.
пояснения написать?

Автор: volvo 23.11.2006 5:58

Да... Вот теперь меня и интересуют пояснения, ПОЧЕМУ один и тот же код по-твоему при использовании классов выдаст одно, а при использовании объектов - другое... Объяснение этому факту приведи, пожалуйста... (я надеюсь это не "проверено на компиляторе"? Меня интересует логика...)

Автор: Vardes 23.11.2006 6:20

Ух ты!!!!
Какое здесь обсуждение завели,спасибо вам...теперь хоть стал немного разбираться...Но возникли ещё вопросы по поводу визуальных компонент....
Есть такой класс в Delphi,как TStaticText,я его использую,для просмотра значения переменной в цикле (цикл большой,от 1000),ну так вот,где-то первые значения мне строка показывает,а потом переменные перестают выводиться на экран в течение цикла, как только он заканчивается выводится последний результат.Из-за чего такое может быть?И ещё....никак не могу понять как работать с классом TspinEdit...могли бы вы привести пример для задания значения переменной?Заранее спасибо smile.gif

Автор: мисс_граффити 23.11.2006 6:43

по-моему, после такой дискуссии начать разбираться нереально. smile.gif
volvo, в общем это.... знаний немного, так что на 90% собственное домысливание (с применением женской логики). соответственно, могу ошибаться...
отталкивалась от того, что object есть и в паскале, а class - только в делфи. (коряво по терминологии, понимаю, что глупо сравнивать язык и среду... но, думаю, идею уловил).
object оставили, как мне кажется, для совместимости...
а раз для совместимости - значит, работать они должны по тому же принципу, что и в паскале (а иначе какой смысл?). что такое override паскаль не знает, а что такое virtual - прекрасно понимает. поскольку у нас есть конструктор (хоть и пустой, на первый взгляд ничего не делающий) - таблица вирт.методов создается как положено. итак, раз virtual, надо использовать метод потомка.
теперь пример с классами. делфи про override прекрасно знает. а раз его нет - значит, и перекрывания не происходит (а чего перекрывать, если не просят?)...

Vardes, по второму вопросу:

a:integer;
...
a:=SpinEdit1.Value;

Автор: Vardes 23.11.2006 12:06

Хотелось бы ещё узнать про TStaticTest...как можно увеличить в этом классе дину строки,а то показывает мне только 14 знаков после запятой (у меня так переменная меняется),а надо больше)

Автор: мисс_граффити 23.11.2006 13:20

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

Автор: Vardes 23.11.2006 16:16

Просто этот компонент показывает изменение переменной....но мне необходимо,чтоб он показывал больше знаков после запятой,а не 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 23.11.2006 16:23

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 23.11.2006 22:22

Понял,что FloatToStrF тоже мне не поможет,может у кого-нить есть пример функции по переводу из действительного типа в строковый?НУ самодельная... cool.gif

Автор: volvo 23.11.2006 22:44

StaticText1.Caption:=FloatToStr(err, ffFixed, 18, 18);

тоже не получается? Неужели трудно F1 нажать?

Автор: Vardes 23.11.2006 22:57

Да меня сначала на форум тянет,а потом я в справку лезу и нахожу там ответы на свои вопросы,так противно за себя становится,я буду пытаться исправится.
FloatToStrF,тоже не подойдёт...после запятой надо ещё больше цифр,ну да и хрен с ним...обойдусь как-нить,буду надеяться,что значение функции будет выше,а не стремится к 0)

Автор: мисс_граффити 23.11.2006 23:54

ну, больше их не станет независимо от метода перевода.