По первому тесту выполнил дважды задания. Результат получается правильный (проверял калькулятором). Пишет, что "Задание не проверено" и предлагает повторить. |
Объектно-ориентированное программирование
9.4 Перегрузка операций
В FreePascal можно перегрузить не только функции, но и операции. Например, можно запрограммировать, чтобы операция * при работе с матрицами осуществляла умножение матриц, а при работе с комплексными числами — умножение комплексных чисел.
Для этого в программе нужно написать специальную функцию — метод. Объявление метода перегрузки записывается после объявления класса и выглядит так:
operator symbols (параметры: тип) имя_переменной_результата: тип;
где
- operator — служебное слово;
- symbols — символ перегружаемой операции;
- параметры — имена переменных, участвующих в перегрузке оператора.
Описывают метод перегрузки так же, как и другие методы, после ключевого слова implemention того модуля, в котором объявлен класс.
Рассмотрим несколько примеров.
На форме разместим четыре компонента типа TEdit для ввода действительной и мнимой частей двух комплексных чисел. Также создадим компонент типа TMemo для вывода результатов и кнопку. При щелчке по кнопке создаются четыре объекта типа "комплексное число". Первое и второе числа инициализируются введенными данными. Третье формируется как результат сложения первых двух, а четвёртое — как разность этих же чисел. Текст программы с комментариями приведён ниже, на рис. 9.4 показано окно работы программы.
unit Unit1; {$mode objfpc}{$H+} interface uses Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls; type { TForm1 } TForm1 = class (TForm) Button1 : TButton; //для ввода действительной части первого числа Edit1 : TEdit; //для ввода мнимой части первого числа Edit2 : TEdit; //для ввода действительной части второго числа Edit3 : TEdit; //для ввода мнимой части второго числа Edit4 : TEdit; Label1 : TLabel; Label2 : TLabel; Label3 : TLabel; Label4 : TLabel; Label5 : TLabel; Label6 : TLabel; Memo1 : TMemo; //поле для вывода результатов procedure Button1Click ( Sender : TObject ); private { private declarations } public { public declarations } end; //объявление класса "комплексное число" type TComplex = class private x : real; //действительная часть y : real; //мнимая часть public constructor Create; //конструктор function Modul ( ) : real; function Argument ( ) : real; function ComplexToStr ( ) : String; end; //объявление метода перегрузки //оператора "+" с комплексными числами operator +(const a, b : TComplex ) r : TComplex; //объявление метода перегрузки //оператора "_" с комплексными числами operator -( const a, b : TComplex ) r : TComplex; var Form1 : TForm1; //объявление переменных типа "комплексное число" chislo1 : Tcomplex; chislo2 : TComplex; chislo3 : TComplex; chislo4 : TComplex; implementation //Описание конструктора. constructor TComplex. Create; begin x : = 0; y : = 0; inherited Create; end; function TComplex. Modul ( ) : real; begin modul:= sqrt ( x * x+y * y ); end; function TComplex. Argument ( ) : real; begin argument := arctan ( y/x ) * 180/ pi; end; //Метода перегрузки оператора "+". //переменные a и b - комплексные числа, //которые складываются, //r - результирующее комплексное число operator +(const a, b : TComplex ) r : TComplex; begin r :=TComplex. Create; //инициализация объекта //Действительная часть нового комплексного //числа формируется как результат сложения //действительных частей первого и второго //операндов. Мнимая часть нового комплексного //числа формируется как результат сложения //мнимых частей первого и второго операндов. //Операнды - переменные типа комплексное //число, передаваемые в метод. r. x:=a. x+b. x; r. y:=a. y+b. y; end; //метод перегрузки оператора "-" operator -( const a, b : TComplex ) r : TComplex; begin r :=TComplex. Create; r. x:=a. x-b. x; r. y:=a. y-b. y; end; function TComplex. ComplexToStr ( ) : String; //Действительная часть нового комплексного //числа формируется как разность действительных //частей первого и второго операндов. Мнимая //часть нового комплексного числа формируется //как разность мнимых частей первого и второго //операндов. Операнды — переменные типа //комплексное число, передаваемые в метод. begin if y>=0 then ComplexToStr := FloatToStrF ( x, ffFixed,5,2)+ ’+ ’ + FloatTostrF ( y, ffFixed,5,2)+ ’ i ’ else ComplexToStr := FloatTostrF ( x, ffFixed,5,2)+ FloatTostrF ( y, ffFixed,5,2)+ ’ i ’ end; procedure TForm1. Button1Click ( Sender : TObject ); var Str1 : String; begin //инициализация объектов chislo1:=TComplex. Create; chislo2:=TComplex. Create; chislo3:=TComplex. Create; chislo4:=TComplex. Create; //чтение действительной и мнимой частей двух исходных //комплексных чисел с формы chislo1.x:= StrToFloat ( Edit1. Text ); chislo1.y:= StrToFloat ( Edit2. Text ); chislo2.x:= StrToFloat ( Edit3. Text ); chislo2.y:= StrToFloat ( Edit4. Text ); //для сложения двух комплексных чисел можно использовать //операцию "+", так как она перегружена для этого класса chislo3:= chislo1+chislo2; //для вычитания двух комплексных чисел можно использовать //операцию "_", так как она перегружена для этого класса chislo4:= chislo1 - chislo2; Str1 := ’ chislo1+chislo2 ’+chislo3. ComplexToStr ( ); Memo1. Lines.Add( Str1 ); Str1 := ’ Modul chisla ’+ FloatToStrF ( chislo3. Modul ( ), ffFixed, 5, 2 ); Memo1.Lines.Add( Str1 ); Str1 := ’ Argument chisla ’+ FloatToStrF ( chislo3.Argument ( ), ffFixed, 5, 2 ); Memo1. Lines.Add( Str1 ); Str1 := ’ chislo1-chislo2 ’+chislo4. ComplexToStr ( ); Memo1. Lines.Add( Str1 ); Str1 := ’ Modul chisla ’+ FloatToStrF ( chislo4.Modul ( ), ffFixed, 5, 2 ); Memo1. Lines. Add( Str1 ); Str1 := ’ Argument chisla ’+ FloatToStrF ( chislo4.Argument ( ), ffFixed, 5, 2 ); Memo1. Lines.Add( Str1 ); end; initialization {$I unit1.lrs} end.