Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
все ответы.docx
Скачиваний:
8
Добавлен:
26.09.2019
Размер:
2.71 Mб
Скачать

19. Методы как составляющие элементы класса. Модификаторы и селекторы пример № 3. Класс “товар”

В описании класса «Товар»:

  1. Поля «Название», «Цена», «Скидка» должны быть недоступны для непосредственного чтения/изменения их значений со стороны других объектов;

  2. Значение поля «Цена» не может быть отрицательным;

  3. Значение поля «Скидка» должно находиться в диапазоне от 0 до 100%.

  • МОДУЛЬ С ОПИСАНИЕМ КЛАССА “ТОВАР” (Stock.pas)

UNIT Stock;

INTERFACE

TYPE

Tovar = class // Описание класса Товар

private // СКРЫТЫЕ ПОЛЯ

Name : String[10]; // Название товара

Price:Double; // Цена

Disc:Integer; // Скидка

public // ДОСТУПНЫЕ МЕТОДЫ

Constructor Create(Nm:String; Pr:Double); // Конструктор - создание товара

Destructor Kill; // Деструктор - удаление товара

procedure SetPrice(N:Double); // Модификатор - изменение цены

procedure SetDisc(D:Integer); // Модификатор - изменение скидки

function GetName():String; // Селектор - выбор имени

function GetPriceD():Double; // Селектор - расчет цены со скидкой

end;

IMPLEMENTATION

{ Tovar - реализация методов}

constructor Tovar.Create(Nm: String; Pr:Double);

begin

Name:=Nm;

if Pr<0 then Price:=0

else Price:=pr;

end;

destructor Tovar.Kill;

begin

// Пустой деструктор, освобождает память, занимаемую объектом

end;

procedure Tovar.SetDisc(D: Integer);

begin

if (D<0)or(D>100) then Disc:=0 // Если задаваемое значение скидки вне диапазона 0..100, скидка равна 0

else Disc:=D;

end;

procedure Tovar.SetPrice(N: Double);

begin

if N<0 then Price:=0 // Если задана отрицательная цена, ее значение обнуляется

else Price:=N;

end;

function Tovar.GetName: String;

begin

GetName:=Name;

end;

function Tovar.GetPriceD:Double;

begin

Result:= (100-Disc)/100*Price // Расчет цены-со-скидкой

end;

END.

  • Примечание. Предопределенная локальная переменная Result задает значение, возвращаемое функцией.

  • МОДУЛЬ ГЛАВНОЙ ФОРМЫ (MainForm.pas)

UNIT MainForm;

INTERFACE

Uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons; {необходимый для работы формы набор модулей из VCL, пополняется при добавлении компонентов на форму}

TYPE

// ОБЪЯВЛЕНИЕ КЛАССА-ФОРМЫ

TForm1 = class(TForm)

Memo1: TMemo;

btnCreate: TButton;

Edit1: TEdit;

Edit2: TEdit;

lblName: TLabel;

lblPrice: TLabel;

gbNew: TGroupBox;

btnListClear: TButton;

gbChange: TGroupBox;

lblNewPrice: TLabel;

lblNewDisc: TLabel;

Edit3: TEdit;

Edit4: TEdit;

btnChange: TButton;

gbList: TGroupBox;

bbtnClose: TBitBtn;

procedure btnCreateClick(Sender: TObject);

procedure btnListClearClick(Sender: TObject);

procedure btnChangeClick(Sender: TObject);

procedure bbtnCloseClick(Sender: TObject);

end;

// ОБЪЯВЛЕНИЕ ОБЪЕКТА-ФОРМЫ

VAR

Form1: TForm1; { объявление объекта формы (инициализация форм происходит в файле проекта )}

IMPLEMENTATION

{$R *.dfm} // Директива включения в исполняемый файл настроек формы

uses Stock; // Подключение модуля с описанием класса Товар (Tovar)

{ Описания приводимых ниже констант, типов, переменных будут недоступны для внешних модулей. Почему? }

Const

NT=10; // Максимальное число товаров в списке T

Type

Tovs=Array[1..NT] of Tovar; // Тип: массив из NT объектов-товаров

Var

T:Tovs; // Массив объектов-товаров

N:Integer=0; // Текущее число объектов-товаров в массиве (N<=NT)

// РЕАЛИЗАЦИЯ МЕТОДОВ КЛАССА TFORM1

{ ДОБАВЛЕНИЕ ТОВАРА В СПИСОК }

procedure TForm1.btnCreateClick(Sender: TObject);

begin

IF N<NT then

Begin

N:=N+1; // Увеличение счетчика товаров

T[N]:=Tovar.Create(Edit1.Text, StrToFloat(Edit2.Text)); // Создание нового объекта (вызов конструктора)

Memo1.Lines.Add(T[N].GetName+':'+FloatToStr(T[N].GetPriceD));// Вывод сведений в Memo-поле

gbChange.Visible:=True; // Доступность компонентов для изменения цены и скидки

end;

end;

{ УДАЛЕНИЕ ВСЕХ ТОВАРОВ ИЗ СПИСКА }

procedure TForm1.btnListClearClick(Sender: TObject);

var

i:Integer;

begin

For I:=1 to N do T[i].Kill; // Удаление всех товаров из массива объектов (вызов деструктора)

N:=0;

Memo1.Clear; // Очистка memo-поля

gbChange.Visible:=False; // Сокрытие компонентов для изменения цены и скидки

end;

{ ЗАКРЫТИЕ ГЛАВНОЙ ФОРМЫ }

procedure TForm1.bbtnCloseClick(Sender: TObject);

var

i:Integer;

begin

For I:=1 to N do T[i].Kill; // Удаление всех товаров из массива объектов (вызов деструктора)

end;

{ ИЗМЕНЕНИЕ ХАРАКТЕРИСТИК ВЫБРАННОГО ТОВАРА (курсор в memo-поле должен указывать на нужную позицию) }

procedure TForm1.btnChangeClick(Sender: TObject);

VAR

nn:Integer;

begin

NN:=Memo1.CaretPos.Y+1; // Определение номера строки в memo-поле, сопоставление его с элементом массива

if NN<=N then // Если в массиве существует объект с номером NN

begin

{Если заданы новая цена и/или скидка для объекта-товара - изменяем их}

if Edit3.Text<>'' then T[NN].SetPrice(StrToFloat(Edit3.Text));

if Edit4.Text<>'' then T[NN].SetDisc(StrToInt(Edit4.Text));

{Изменение содержимого соответствующей строки Memo-поля}

Memo1.Lines.Delete(NN-1);

Memo1.Lines.Insert(NN-1,T[NN].GetName+':'+FloatToStr(T[NN].GetPriceD));

End

Else

ShowMessage('Установите в списке курсор на нужный товар')

end;

END.

  • Примечания.

  1. Memo1.CaretPos.Y – определение вертикальной координаты Y курсора в memo-поле (совпадает с номером строки). Т.к. нумерация строк в memo-поле начинается с 0, то для ее сопоставления с товаром в массиве [1..NT] добавляем 1.

  2. Memo.Lines.Delete(index:integer) - удаляет элемент с номером index.

    • Добавьте в текст модуля проверку корректности значений, вводимых в поля Edit1, Edit2, Edit3, Edit4.

    • Отметьте невозможность прямого обращения к полям объекта Товар из текущего модуля (например, замены метода T[i].GetName на T[i].Name, T[i].SetPrice на T[i].Price:=1000 и т.п.)

  3. Memo.Lines.Insert(index:Integer; const S:String) - вставляет строку S в позицию index.