Ужыванне інтэрфейсаў у ААП у PHP

Такім чынам, мы ўжо высветлілі, што інтэрфейсы - добры спосаб кантраляваць тое, што рэалізаваны ўсе неабходныя метады класа.

Давайце разгледзім яшчэ адзін, больш практычны, прыклад. Хай у нас ёсць клас, які будзе захоўваць у сабе масіў аб'ектаў-фігур:

FiguresCollection.php<?php
  class FiguresCollection
  {
    private $figures = []; // масіў для фігур
  }
?>

Рэалізуем у нашым класе метад addFigure для дадання аб'ектаў у калекцыю:

FiguresCollection.php<?php
  class FiguresCollection
  {
    private $figures = [];
    
    // Параметрам перадаецца аб'ект з фігурай:
    public function addFigure($figure)
    {
      $this->figures[] = $figure;
    }
  }
?>

Відавочна, што мы разлічваем на тое, што параметрам метаду addFigure будзе перадавацца аб'ект з фігурай. Аднак за гэтым няма ніякага кантролю!

Давайце выкарастаем падказку для тыпаў і явна ўкажам тып аб'ектаў як Figure:

FiguresCollection.php<?php
  class FiguresCollection
  {
    private $figures = [];
    
    public function addFigure(Figure $figure)
    {
      $this->figures[] = $figure;
    }
  }
?>

Давайце разбяромся з тым, што мы зрабілі.

Калі б Figure быў рэальна існуючым класам, то ў параметр метаду мы змаглі б перадаць аб'екты гэтага класа, а таксама і яго спадчынікаў.

У нас, аднак, Figure - гэта інтэрфейс. У такім выпадку падказка абазначае тое, што параметрам метаду могуць быць перададзены толькі аб'екты класа, якія рэалізуюць наш інтэрфейс.

Давайце паспрабуем стварыць аб'ект нашага класа і дадаць у яго фігуры:

index.php<?php
  $figuresCollection = new FiguresCollection;
  
  // Дадамо пару квадратаў:
  $figuresCollection->add(new Quadrate(2));
  $figuresCollection->add(new Quadrate(3));
  
  // Дадамо пару прамавугольнікаў:
  $figuresCollection->add(new Rectangle(2, 3));
  $figuresCollection->add(new Rectangle(3, 4));
?>

Спроба дадаць аб'ект якога-небудзь іншага класа прывядзе да памылкі:

index.php<?php
  $figuresCollection = new FiguresCollection;
  
  class Test {}; // нейкі іншы клас
  $figuresCollection->add(new Test); // выдзе памылку
?>

Што на практыцы дае нам такі кантроль: так як усе фігуры, дададзеныя ў калекцыю, рэалізуюць інтэрфейс Figure, мы можам быць упэўненыя, што ў кожнай з іх будзе метад getSquare і метад getPerimeter.

Магчыма ў далейшым акрамя квадрата і прамавугольніка з'явіцца, напрыклад, яшчэ і трохвугольнік. У гэтым выпадку і ў трохвугольніка таксама будуць метады getSquare і getPerimeter.

На практыцы гэта дае нам наступнае: мы можам у класе FiguresCollection зрабіць, напрыклад, метад getTotalSquare, які знаходзіць поўную плошчу фігур калекцыі. У гэтым метадзе мы будзем перабіраць цыклам масіў фігур і у кожнай фігуры выклікаць метад getSquare.

Так як кожная фігура рэалізуе інтэрфейс Figure, мы можам быць на 100% упэўненыя ў тым, што ў кожнай фігуры будзе гэты метад getSquare.

Такім чынам, вось рэалізацыя метаду:

php<?php
  class FiguresCollection
  {
    private $figures = [];
    
    public function addFigure(Figure $figure)
    {
      $this->figures[] = $figure;
    }
    
    // Знайдзем поўную плошчу:
    public function getTotalSquare()
    {
      $sum = 0;
      
      foreach ($this->figures as $figure) {
        $sum += $figure->getSquare(); // выкарыстоўваем метад getSquare
      }
      
      return $sum;
    }
  }
?>
Задание 1

Не падглядваючы ў мой код рэалізуйце такі жа клас FiguresCollection.

Задание 2

Дадайце ў клас FiguresCollection метад getTotalPerimeter для знаходжання сумарнага перыметра ўсіх фігур.