Имееться модуль:
unit OOP4;
interface
uses
SysUtils, Variants, Classes;
type
TRational = class
private
FA,FB:longint;
function Reduce(FRational:TRational):TRational;
public
function Add(FRational:Trational;fc,fd:longint):TRational;
//function Sub(FRational:Trational;fc,fd:longint):TRational;
//function Mul(FRational:Trational;fc,fd:longint):TRational;
//function Di(FRational:Trational;fc,fd:longint):TRational;
//function Com(fc,fd:longint; FRational:Trational):string;
Constructor Create(A,B: longint);
Destructor Destroy;
end;
implementation
function TRational.Reduce(FRational:TRational):TRational;
var
i,NOD:Integer;
R:TRational;
begin
for i:=1 to FRational.FA do if (FRational.FA mod i = 0) and (FRational.FB mod i = 0) then NOD:=i;
R:=TRational.Create(FRational.FA div NOD,FRational.FB div NOD);
Result:=R;
end;
function TRational.Add(FRational:Trational;fc,fd:longint):TRational;
var
R:TRational;
begin
R:=TRational.Create(FRational.FA*fd+FRational.FB*FC,FRational.FB*FD);
Result:=FRational.Reduce(R);
end;
Constructor TRational.Create(a,b:longint);
begin
inherited Create;
fa:=a;
fb:=b;
end;
destructor TRational.Destroy;
begin
inherited Destroy;
end;
end.
основная программа:
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, OOP4, StdCtrls, ExtCtrls, math;
type
TForm1 = class(TForm)
Button1: TButton;
LabeledEdit1: TLabeledEdit;
LabeledEdit2: TLabeledEdit;
LabeledEdit3: TLabeledEdit;
LabeledEdit4: TLabeledEdit;
ListBox1: TListBox;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
A,B,C,D,TA,TB:Longint;
DR,DF:TRational;
begin
ListBox1.Clear;
A:=strtoint(LabeledEdit1.Text);
B:=strtoint(LabeledEdit2.Text);
C:=strtoint(LabeledEdit3.Text);
D:=strtoint(LabeledEdit4.Text);
DR:=TRational.Create(A,B);
DR.Destroy;
end;
end.
как можно занести в листбокс результаты выполнения функции Add?
Другие языки программирования и технологии
Помогите с классами в Delphi.
Если не брать во внимание private и public, то это и не ТР. Ваш класс, это класс рациональной дроби. А что есть у дроби? Правильно, числитель и знаменатель. Это поля класса, причем они должны быть спрятаны ото всех. А для этого их следует поместить в секцию private. Это сделано. С другой стороны, эти самые числитель и знаменатель как-то должны светиться, иначе какой смысл в экземпляре класса, содержащем какие-то данные, если их невозможно увидетть? Вот для этого и существуют свойства. Они могут быть доступнв по чтению или по записи, или одновременно по чтению и по записи. В вашем случае достаточно только по чтению, т. к. изменение числителя и знаменатель возможно только в результате каких-то арифметических действий с дробью и эта задача отводится методам. Объявление свойства помещается в секцию public и имеет вид
public
property A: LongInt read FA;
property B: Longint read FB;
Теперь методы. С имеющимися числителем и знаменателем, т. е. с дробью, можно выполнять некоторые действия. Например, сложить ее с другой дробью. Сделать это можно методом Add. У вас предпринята такая попытка, но не понятно, зачем среди параметров присутствуют fc,fd и для чего этот метод реализован в виде функции? Методу достаточно указать, с какой другой дробью надо сложить собственные данные, которые в результате сложения изменяться. Делать это можно и процедурой.
procedure Add(FRational:TRational);
Аналогично и с Reduce. Ее назначение выполнить сокращение дроби. И выполнячется оно опять-таки над собственными данными после выполнения операции с ними.
Тогда в основной программе вы сможете создать экземпляры класса
DR:=TRational.Create(A,B);
DF:=TRational.Create(C,D);
И выполнить, например, сложение первого со вторым.
DR.Add(DF);
После чего можно обратиться к свойствам А и В. А можно объявить еще одно свойство (View), которое будет возвращать в виде строки значение числителя и знаменателя, разделенные слешем. И вот значение этого свойства вы сможете поместить в мемо или еще куда.
Memo1.Lines.Add(DR.View);
Можно пойти и по другому пути и методы, реализующие арифметические действия, оформить в виде функций, возвращающий ссылки на экземпляры класса у которых установленные свойства будут равны результату соответствующего действия. В этом случае можно будет выполнять присвоение значения переменной соответствующего типа.
DK := DR.Add(DF);
В общем, вариантов здесь куча и все зависит от конкретного задания.
И последнее. Поскольку вы свой класс не наследуете, то и нет смысла в кострукторе и деструкторе вызывать методы не существующего предка. Боюсь, компилятор ругнется на это дело.
public
property A: LongInt read FA;
property B: Longint read FB;
Теперь методы. С имеющимися числителем и знаменателем, т. е. с дробью, можно выполнять некоторые действия. Например, сложить ее с другой дробью. Сделать это можно методом Add. У вас предпринята такая попытка, но не понятно, зачем среди параметров присутствуют fc,fd и для чего этот метод реализован в виде функции? Методу достаточно указать, с какой другой дробью надо сложить собственные данные, которые в результате сложения изменяться. Делать это можно и процедурой.
procedure Add(FRational:TRational);
Аналогично и с Reduce. Ее назначение выполнить сокращение дроби. И выполнячется оно опять-таки над собственными данными после выполнения операции с ними.
Тогда в основной программе вы сможете создать экземпляры класса
DR:=TRational.Create(A,B);
DF:=TRational.Create(C,D);
И выполнить, например, сложение первого со вторым.
DR.Add(DF);
После чего можно обратиться к свойствам А и В. А можно объявить еще одно свойство (View), которое будет возвращать в виде строки значение числителя и знаменателя, разделенные слешем. И вот значение этого свойства вы сможете поместить в мемо или еще куда.
Memo1.Lines.Add(DR.View);
Можно пойти и по другому пути и методы, реализующие арифметические действия, оформить в виде функций, возвращающий ссылки на экземпляры класса у которых установленные свойства будут равны результату соответствующего действия. В этом случае можно будет выполнять присвоение значения переменной соответствующего типа.
DK := DR.Add(DF);
В общем, вариантов здесь куча и все зависит от конкретного задания.
И последнее. Поскольку вы свой класс не наследуете, то и нет смысла в кострукторе и деструкторе вызывать методы не существующего предка. Боюсь, компилятор ругнется на это дело.
Тим
Предок то есть - это TObject. даже если в описании класса TRational = class - по умолчанию все равно TObject. Другое дело деструктор у TObject виртуальный ...
Не по теме:
DR.Destroy;
За прямой вызов деструктора в дельфи принято бить канделябром.
По теме:
Опиши внутри своего класса переменную типа TStringList и складывай туда что хочешь. Потом можешь вывести куда надо. Не забудь создать и освободить объект TStringList.
DR.Destroy;
За прямой вызов деструктора в дельфи принято бить канделябром.
По теме:
Опиши внутри своего класса переменную типа TStringList и складывай туда что хочешь. Потом можешь вывести куда надо. Не забудь создать и освободить объект TStringList.
Алексей Мальцев
А как тогда освобождать? Если не прямым деструктором?
Это явно не Delphi, это кусок класса на Turbo Pascal. Совершенно не ясна судьба результатов функций Reduce и Add. Думаю надо сделать какое-то свойство подобное Tlist только более интеллектуальное и на него завязать результаты этих функций. Тогда думаю проблема отпадет сама собой
Алексей Мальцев
Вот я по поводу результатов этих функций и интересуюсь, как их можно получить в основном модуле?
Попытаюсь быть кратким:
Реализация класса TRational весьма далека от совершенства. Предлагаю
1.дать доступ к полям fa и fb - в конце секции public добавить
property A:Longint read fa write fa;
property B:Longint read fb write fb;
2.Деструктор пустой - убрать совсем
3.Метод Reduce должен работать со своими полями, а не с чужими (иначе зачем класс? )
procedure TRational.Reduce;
var
i,NOD:Integer;
begin
for i:=1 to A do if (A mod i = 0) and (B mod i = 0) then NOD:=i;
A := A div NOD; B := B div NOD;
end;
4.Метод Add аналогично
procedure TRational.Add(fc,fd:longint);
begin
A := A*fd+B*FC; B := B * fd;
Reduce;
end;
5.Ну и в "главной программе":
DR:=TRational.Create(A,B);
DR.Add(C,D);
ListBox1.items.Add('A='+IntTostr(DR.A)+' B ='+IntTostr(DR.B) );
DR.Free;
Не надо плодить лишних сущностей - экземпляр класса и есть результат.
Реализация класса TRational весьма далека от совершенства. Предлагаю
1.дать доступ к полям fa и fb - в конце секции public добавить
property A:Longint read fa write fa;
property B:Longint read fb write fb;
2.Деструктор пустой - убрать совсем
3.Метод Reduce должен работать со своими полями, а не с чужими (иначе зачем класс? )
procedure TRational.Reduce;
var
i,NOD:Integer;
begin
for i:=1 to A do if (A mod i = 0) and (B mod i = 0) then NOD:=i;
A := A div NOD; B := B div NOD;
end;
4.Метод Add аналогично
procedure TRational.Add(fc,fd:longint);
begin
A := A*fd+B*FC; B := B * fd;
Reduce;
end;
5.Ну и в "главной программе":
DR:=TRational.Create(A,B);
DR.Add(C,D);
ListBox1.items.Add('A='+IntTostr(DR.A)+' B ='+IntTostr(DR.B) );
DR.Free;
Не надо плодить лишних сущностей - экземпляр класса и есть результат.
Похожие вопросы
- Помогите составить задачу в Delphi
- программисты помогите срочно задача на Delphi
- помогите составить калькулятор на Delphi ?
- помогите написать программу на Delphi
- Помогите сделать проект по Delphi ПОЖАЛУЙСТА...
- Помогите с базой данных Delphi+Access
- Помогите с кодом в Delphi, пожалуйста!
- Пожалуйста, помогите с задачкой на Delphi
- Помогите составить задачу в Delphi
- Помогите решить задачу в Delphi срочно! буду очень благодарен.