[Bài đọc] Interface

Lập trình Hướng Đối tượng

Interface khai báo giống cách chúng ta khai báo một lớp, nhưng ta dùng từ khoá interface thay cho class và các phương thức bên trong không có phần thân (chỉ có khai báo).

Tất cả các phương thức được định nghĩa trong một interface phải được khai báo là public; đó là đặc tính của interface.

Triển khai

Để triển khai (sử dụng\cài đặt) một interface người ta sử dụng toán tử (từ khóa) implements khi định nghĩa một lớp mới từ Interface. Lớp triển khai interface phải định nghĩa cho tất cả các phương thức được mô tả trong interface;  nếu không thực hiện việc đó sẽ gây ra lỗi. Các lớp có thể triển khai\kế thừa nhiều hơn một interface, chúng được phân cách nhau bởi dấu phẩy.

Lưu ý:

  • Từ phiên bản PHP 5.3.9 trở về trước, một class không thể triển khai hai interface mô tả phương thức trùng tên nhau, vì nó sẽ gây ra sự thiếu rõ ràng. Những phiên bản PHP gần đây đã cho phép các phương thức trùng nhau miễn là chúng phải đảm bảo cùng tên, cùng danh sách và thứ tự tham số (same signature).
  • Một interface có thể kế thừa interface khác giống như lớp bằng cách sử dụng toán tử (từ khóa) extends.
  • Class kế thừa interface phải triển khai chính xác phương thức đã được mô tả trong interface (cùng tên, cùng danh sách và thứ tự tham số). Nếu không đảm bảo điều này sẽ phát sinh lỗi.

Các hằng giá trị

Các interface có thể có thêm các hằng giá trị. Hằng giá trị của interface giống với các hằng giá trị trong lớp, ngoại trừ chúng không được ghi đè (override) bởi các lớp hay inteface kế thừa chúng.

Các ví dụ

VD 1: Interface

<?php 
 
// Declare the interface 'iTemplate'
interface iTemplate
{
    public function setVariable($name, $var);
    public function getHtml($template);
}
 
// Triển khai interface iTemplate
// Thực hiện đúng, mã không lỗi
class Template implements iTemplate
{
    private $vars = array();
  
    public function setVariable($name, $var)
    {
        $this->vars[$name] = $var;
    }
  
    public function getHtml($template)
    {
        foreach($this->vars as $name => $value) {
            $template = str_replace('{' . $name . '}', $value, $template);
        }
 
        return $template;
    }
}
 
// Thực hiện sai, mã gặp lỗi
// Fatal error: Class BadTemplate contains 1 abstract methods
// Nguyên nhân: Không cài đặt phương thức getHtml() đã mô tả trong iTemplate
class BadTemplate implements iTemplate
{
    private $vars = array();
  
    public function setVariable($name, $var)
    {
        $this->vars[$name] = $var;
    }
}
?>


VD 2: Kế thừa Interface

<?php 
interface A
{
    public function foo();
}
 
interface B extends A
{
    public function baz(Baz $baz);
}
 
// Thực hiện đúng, mã không gặp lỗi
class C implements B
{
    public function foo()
    {
    }
 
    public function baz(Baz $baz)
    {
    }
}
 
// Thực hiện sai, gặp lỗi fatal error
class D implements B
{
    public function foo()
    {
    }
 
    public function baz(Foo $foo)
    {
    }
}
?>


VD 3: Triển khai nhiều interface


<?php 
 
interface A
{
    public function foo();
}
 
interface B
{
    public function bar();
}
 
interface C extends A, B
{
    public function baz();
}
 
class D implements C
{
    public function foo()
    {
    }
 
    public function bar()
    {
    }
 
    public function baz()
    {
    }
}
?>


VD 4: Các hằng giá trị của interface


<?php 
interface A
{
    const VALUE = 'Interface constant';
}
 
// Hiển thị thuộc tính hằng giá trị
echo A::VALUE;
 
// Mã gặp lỗi do ghi đè thuộc tính hằng giá trị 
class B implements A
{
    const VALUE = 'Class constant';
}

?>


Một interface, cùng với type-hinting (gợi ý kiểu dữ liệu), cho ta một giải pháp tốt để đảm bảo việc một đối tượng cụ thể nào đó có các phương thức cụ thể. Xem thêm về toán tử instanceof và type-hinting.

Bài viết được dịch từ :  http://php.net

Leave a Reply

Your email address will not be published. Required fields are marked *