Liideste kasutamine OOP-s PHP-s

Nii, me juba selgitasime välja, et liidesed on hea viis kontrollida, et kõik vajalikud klassi meetodid on realiseeritud.

Vaatame veel üht, praktilisemat, näidet. Oletame, et meil on klass, mis salvestab endas kujundite objektide massiivi:

FiguresCollection.php<?php
  class FiguresCollection
  {
    private $figures = []; // massiiv kujundite jaoks
  }
?>

Rakendame oma klassis meetodi addFigure objektide lisamiseks kollektsiooni:

FiguresCollection.php<?php
  class FiguresCollection
  {
    private $figures = [];
    
    // Parameetrina edastatakse kujundiga objekt:
    public function addFigure($figure)
    {
      $this->figures[] = $figure;
    }
  }
?>

Ilmselgelt arvestame me sellega, et meetodi addFigure parameetriks edastatakse kujundiga objekt. Kuid selle järele puudub igasugune kontroll!

Kasutame tüübi vihjet ja määrame selgelt objektide tüübiks Figure:

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

Mõtleme välja, mida me tegime.

Kui Figure oleks tegelikult eksisteeriv klass, siis meetodi parameetriks saaksime edastada selle klassi objekte ning ka selle pärijaid.

Meil aga on Figure liides. Sellisel juhul tähendab vihje seda, et meetodi parameetriks saab edastada ainult klassi objekte, mis realiseerivad meie liidest.

Proovime luua oma klassi objekti ja lisada sellesse kujundeid:

index.php<?php
  $figuresCollection = new FiguresCollection;
  
  // Lisame paari ruutu:
  $figuresCollection->add(new Quadrate(2));
  $figuresCollection->add(new Quadrate(3));
  
  // Lisame paari ristkülikut:
  $figuresCollection->add(new Rectangle(2, 3));
  $figuresCollection->add(new Rectangle(3, 4));
?>

Teise klassi objekti lisamise katse viib veani:

index.php<?php
  $figuresCollection = new FiguresCollection;
  
  class Test {}; // mingi teine klass
  $figuresCollection->add(new Test); // annab vea
?>

Mida selline kontroll meile praktikas annab: kuna kõik kollektsiooni lisatud kujundid realiseerivad liidest Figure, saame olla kindlad, et igal neist on meetod getSquare ja meetod getPerimeter.

Võimalik, et tulevikus peale ruudu ja ristküliku ilmub näiteks veel kolmnurk. Sel juhul on ka kolmnurgal meetodid getSquare ja getPerimeter.

Praktikas annab see meile järgmise: me võime klassis FiguresCollection teha näiteks meetodi getTotalSquare, mis leiab kõigi kollektsiooni kujundite kogupindala. Selles meetodis me tsükliga läbime kujundite massiivi ja igal kujundil kutsume välja meetodi getSquare.

Kuna iga kujund realiseerib liidest Figure, saame olla 100% kindlad selles, et igal kujundil on see meetod getSquare.

Nii, siin on meetodi realiseering:

php<?php
  class FiguresCollection
  {
    private $figures = [];
    
    public function addFigure(Figure $figure)
    {
      $this->figures[] = $figure;
    }
    
    // Leiame kogupindala:
    public function getTotalSquare()
    {
      $sum = 0;
      
      foreach ($this->figures as $figure) {
        $sum += $figure->getSquare(); // kasutame meetodit getSquare
      }
      
      return $sum;
    }
  }
?>
Задание 1

Ärge piiluge minu koodi, realiseerige sama klass FiguresCollection.

Задание 2

Lisage klassi FiguresCollection meetod getTotalPerimeter kõigi kujundite koguümbermõõdu leidmiseks.