Ứng dụng Interface trong OOP PHP
Vậy là chúng ta đã biết rằng interface là một cách tốt để kiểm soát việc tất cả các phương thức cần thiết của lớp đều được triển khai.
Hãy xem xét một ví dụ thực tế hơn. Giả sử chúng ta có một lớp để lưu trữ một mảng các đối tượng hình học:
<?php
class FiguresCollection
{
private $figures = []; // mảng cho các hình
}
?>
Hãy triển khai phương thức addFigure
trong lớp của chúng ta để thêm đối tượng vào bộ sưu tập:
<?php
class FiguresCollection
{
private $figures = [];
// Tham số truyền vào là một đối tượng hình:
public function addFigure($figure)
{
$this->figures[] = $figure;
}
}
?>
Rõ ràng là chúng ta tính toán rằng
tham số của phương thức addFigure sẽ
được truyền vào là một đối tượng hình. Tuy nhiên không có
bất kỳ sự kiểm soát nào cho việc này!
Hãy sử dụng gợi ý kiểu dữ liệu và
chỉ định rõ kiểu đối tượng là Figure:
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
}
?>
Hãy tìm hiểu xem chúng ta đã làm gì.
Nếu Figure là một lớp thực sự tồn tại
thì vào tham số phương thức chúng ta có thể
truyền các đối tượng của lớp đó, cũng như
các lớp con kế thừa từ nó.
Tuy nhiên, Figure của chúng ta - là một interface.
Trong trường hợp này, gợi ý kiểu dữ liệu có nghĩa là
tham số phương thức chỉ có thể là
các đối tượng của lớp triển khai interface của chúng ta.
Hãy thử tạo một đối tượng của lớp chúng ta và thêm các hình vào nó:
<?php
$figuresCollection = new FiguresCollection;
// Thêm một vài hình vuông:
$figuresCollection->add(new Quadrate(2));
$figuresCollection->add(new Quadrate(3));
// Thêm một vài hình chữ nhật:
$figuresCollection->add(new Rectangle(2, 3));
$figuresCollection->add(new Rectangle(3, 4));
?>
Nếu cố gắng thêm một đối tượng của lớp khác sẽ dẫn đến lỗi:
<?php
$figuresCollection = new FiguresCollection;
class Test {}; // một lớp nào đó khác
$figuresCollection->add(new Test); // sẽ báo lỗi
?>
Trong thực tế, sự kiểm soát này mang lại cho chúng ta điều gì:
vì tất cả các hình được thêm vào bộ sưu tập
đều triển khai interface Figure, chúng ta có thể
chắc chắn rằng mỗi hình sẽ có phương thức
getSquare và phương thức
getPerimeter.
Có thể trong tương lai ngoài hình vuông và hình chữ nhật
sẽ xuất hiện, ví dụ, thêm cả hình tam giác. Trong
trường hợp này, hình tam giác cũng sẽ có
các phương thức getSquare và
getPerimeter.
Trong thực tế, điều này mang lại cho chúng ta điều sau: chúng ta có thể
trong lớp FiguresCollection tạo ra,
ví dụ, phương thức getTotalSquare, tìm
tổng diện tích của các hình trong bộ sưu tập. Trong phương thức này
chúng ta sẽ lặp qua mảng các hình bằng vòng lặp và
từng hình gọi
phương thức getSquare.
Vì mỗi hình đều triển khai interface
Figure, chúng ta có thể 100%
chắc chắn rằng mỗi hình sẽ có
phương thức getSquare này.
Vậy, đây là cách triển khai phương thức:
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
// Tìm tổng diện tích:
public function getTotalSquare()
{
$sum = 0;
foreach ($this->figures as $figure) {
$sum += $figure->getSquare(); // sử dụng phương thức getSquare
}
return $sum;
}
}
?>
Không nhìn vào code của tôi, hãy tự triển khai một lớp
FiguresCollection tương tự.
Thêm vào lớp FiguresCollection
phương thức getTotalPerimeter để tìm
tổng chu vi của tất cả các hình.