Введение в объектно-ориентированное программирование на языке Object Pascal. Соколов Е.В. - 39 стр.

UptoLike

Составители: 

39
constructor PAryFraction.CreateAs(n, m: Integer);
var i: Integer;
begin
if m<1 then // знаменатель должен быть положителен
raise Exception.Create('Illegal value of denominator');
if m=1 then begin // определить base невозможно, полагаем равным 2
self.base:=2; self.SetNum(n); self.SetDen(m); exit;
end;
self.base:=0; i:=1;
repeat // выбираем первый простой делитель числа m
inc(i);
if (m mod i)=0 then self.base:=i;
until self.base=i;
self.SetNum(n); self.SetDen(m);
// если m не является степенью base, SetDen вызовет исключение
end;
end.
Реализация методов isPrime, isPowerOfBase и GetBase очевидна.
Процедура SetBase выполняется, лишь когда передаваемое ей значение
отлично от текущего. Поскольку знаменатель должен быть степенью
base, его в этом случае также необходимо менять, и единственный ра-
зумный выход установить все число рав ным 0.
Метод SetDen проверяет, является ли новое значение допустимым
и, если да, вызывает свою старую версию, которая и модифицирует зна-
чение поля. Аналогичным образом реализован конструктор Create, ини-
циализирующий унаследованные поля при помощи конструкт ора класса
Rational. Наконец, конструктор CreateAs пытается определить значение
base по знаменателю. В качестве кандидата выбирается первый же про-
стой делитель числа m, если оно отлично от ед и ницы , и 2 в противном
случае. Завершает проверку корректности метод SetDen (нового класса),
в ы зываемый далее.
Заметим , что заменить выражение
self.SetNum(n); self.SetDen(m);
в реализации данного конструктора инструкцией
inherited CreateAs(n, m);
нельзя, так как старый конструктор вызовет старую же версию метода
SetDen и проверка будет выполнена не в полном объеме.
constructor PAryFraction.CreateAs(n, m: Integer);
  var i: Integer;
  begin
    if m<1 then // знаменатель должен быть положителен
       raise Exception.Create('Illegal value of denominator');
    if m=1 then begin // определить base невозможно, полагаем равным 2
       self.base:=2; self.SetNum(n); self.SetDen(m); exit;
    end;
    self.base:=0; i:=1;
    repeat // выбираем первый простой делитель числа m
       inc(i);
       if (m mod i)=0 then self.base:=i;
    until self.base=i;
    self.SetNum(n); self.SetDen(m);
    // если m не является степенью base, SetDen вызовет исключение
  end;

end.


          Реал из ация м етод ов isPrime , isPowerOfBase и GetBase очев ид на.
Процед ура SetBase в ы пол няет с я, л иш ь когд а перед ав аем ое ей з начение
отл ично от т екущего. Пос кол ь ку з нам енат ел ь д ол жен бы т ь с т епень ю
base, его в э т ом с л учае т акже необход им ом енят ь , и ед инс т в енны й ра-
з ум ны й в ы ход — ус т анов ит ь в с е чис л орав ны м 0.
          М етод SetDen пров еряет, яв л яет с я л и нов ое з начение д опус т им ы м
и, ес л и д а, в ы з ы в ает с в ою с т арую в ерс ию, которая и м од ифицирует з на-
чение пол я. Анал огичны м образ ом реал из ов ан конс т руктор Create, ини-
циал из ирующий унас л ед ов анны е пол я при пом ощи конс т руктора кл ас с а
Rational. Н аконец, конс т руктор CreateAs пы т ает с я опред ел ит ь з начение
base поз нам енат ел ю. В качес т в е канд ид ат а в ы бирает с я перв ы й же про-
с той д ел ит ел ь чис л а m, ес л и оноотл ичноот ед иницы , и 2 в прот ив ном
с л учае. Зав ерш ает пров ерку коррект нос т и м етод SetDen (нов огокл ас с а),
в ы з ы в аем ы й д ал ее.
          Зам ет им , чтоз ам енит ь в ы ражение
                       self.SetNum(n); self.SetDen(m);
в реал из ации д анногоконс т руктора инс т рукцией
                           inherited CreateAs(n, m);
нел ь з я, т ак как с т ары й конс т руктор в ы з ов ет с т арую же в ерс ию м етод а
SetDen и пров ерка буд ет в ы пол нена не в пол ном объем е.




                                         39