PHP да ООПда интерфейслардан фойдаланиш
Шундай қилиб, биз интерфейслар - класснинг барча зарур методлари амалга оширилишини назорат қилишнинг яхши усули эканини аниқладик.
Яна бир, амалийрок, мисолни кўриб чиқайлик. Фарз қилайлик, бизда объект-шакллар массивини сақловчи класс мавжуд:
<?php
class FiguresCollection
{
private $figures = []; // шакллар учун массив
}
?>
Коллекцияга объектлар қўшиш учун бизнинг классда
addFigure методини амалга оширамиз:
<?php
class FiguresCollection
{
private $figures = [];
// Параметр сифатида шакл билан объект ўтказилади:
public function addFigure($figure)
{
$this->figures[] = $figure;
}
}
?>
Аниқки, биз addFigure методининг параметри
сифатида шакл билан объект ўтказилади, деб
ҳисоблаймиз. Аммо бу ҳақида ҳеч қандай назорат йўқ!
Келгина, турлар учун маслиҳатдан фойдаланамиз ва
объектлар турини Figure сифатида аниқ
кўрсатамиз:
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
}
?>
Келгина, биз нима қилганимизни аниқлаб оламиз.
Агар Figure ҳақиқий мавжуд бўлган класс
бўлса, у ҳолда биз метод параметрига шу класснинг
объектларини, шунингдек унинг меросхўрларини
ҳам ўтказишга муваффақ бўлар эдик.
Бизда, аммо, Figure - интерфейс.
Бундай ҳолда маслиҳат шунни англатадики,
метод параметрига фақат бизнинг интерфейсимизни
амалга оширувчи класснинг объектларигина
ўтказилиши мумкин.
Келгина, бизнинг класснинг объектини яратиб, уңга шакллар қўшайлик:
<?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));
?>
Бошқа бир класснинг объектини қўшаш уриниши хатоликка олиб келади:
<?php
$figuresCollection = new FiguresCollection;
class Test {}; // бошқа бир класс
$figuresCollection->add(new Test); // хатолик берadi
?>
Амалда бизга бундай назорат нима беради:
коллекцияга қўшилган барча шакллар
Figure интерфейсини амалга оширгани
сабабли, биз ҳар бирида getSquare методу
ва getPerimeter методу бўлишига ишонч
ҳосил қиламиз.
Эҳтимол кейинроқ квадрат ва тўртбурчакдан
ташқари, масалан, яна учбурчак ҳам пайдо
бўлади. Бу ҳолда учбурчакда ҳам getSquare
ва getPerimeter методлари бўлади.
Амалда бу бизга шунни беради: биз
FiguresCollection классада, масалан,
коллекция шаклларининг тўла юзини топадиган
getTotalSquare методини яратишимиз
мумкин. Бунда методда биз шакллар массивини
цикл билан айлантириб, ҳар бир шаклда
getSquare методини чақирамиз.
Ҳар бир шакл Figure интерфейсини амалга
оширгани сабабли, биз 100% ишонч
ҳосил қиламизки, ҳар бир шаклда ана шу
getSquare методу бўлади.
Шундай қилиб, методнинг амалга оширилиши:
<?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;
}
}
?>
Менинг кодимга қарамай, шунинг ўзидай
FiguresCollection классани амалга оширинг.
FiguresCollection класса
getTotalPerimeter методани қўшинг,
бу барча шаклларнинг умумий периметрини топиш учун.