Phân biệt giao diện interface với lớp trừu tượng abstract class trong php

Khi nào thì dùng interface và khi nào thì dùng abstract class? Sự giống và khác nhau giữa chúng như thế nào?

Abstract class là gì?

  • Lớp trừu tượng(abstract class) đơn giản được xem như một class cha cho tất cả class có cùng bản chất.
  • Mỗi lớp con chỉ có thể kế thừa trực tiếp từ một lớp cha bằng từ khóa extends.
  • Không thể khởi tạo được các đối tượng thuộc lớp abstract.
  • Các phương thức trong abstract class có thể là phương thức abstract hoặc không. Nếu là phương thức abstract thì chỉ được khai báo tên nhưng không viết phần nội dung.
  • Lớp con kế thừa từ lớp abstract phải override các phương thức abstract trong đó.

Interface là gì?

  • Interface không phải là một class, mà là bản thiết kế cho các class có cùng cách thức hoạt động.
  • Không thể định nghĩa các thuộc tính, khởi tạo đối tượng mà chỉ khai báo các phương thức trong interface.
  • Các phương thức chỉ được khai báo tên nhưng không được viết nội dung trong đó.
  • Các phương thức của interface phải để dưới dạng public.
  • Nếu lớp kế thừa từ interface thì phải override tất cả các phương thức trong đó.
  • Một lớp có thể kế thừa từ nhiều interface khác nhau.

Sự khác nhau giữa interface và abstract class

  • Tất cả phương thức trong interface luôn luôn(được hiểu) là abstract.
  • Các phương thức trong abstract class là abstract hoặc không phải là abstract.
  • Có thể implements nhiều interface nhưng không thể extends trực tiếp nhiều class.
  • Các phương thức trong interface luôn luôn phải để là public, khác với abstract class có thể là public, private hoặc protected.

Sự giống nhau giữa interface và abstract class

  • Không thể tạo một biến kiểu interface hoặc abstract class.
  • Nếu là phương thức abstract thì phải được khai báo lại trong class con.
  • Cả interface và abstract class đều có tính kế thừa.

Ví dụ về việc sử dụng interface

<?php
interface MoveInterface
{
    function run();
}
class Dog implements MoveInterface
{
    public function run () 
    {
        echo 'Con chó chạy bằng 4 chân<br>';
    }
}
class Person implements MoveInterface
{
    public function run ()
    {
        echo 'Loài người đi bằng 2 chân<br>';
    }
}
class Car implements MoveInterface
{
    public function run ()
    {
        echo 'Xe hơi chạy bằng 4 bánh';
    }
}
 
 
Dog::run();
Person::run();
Car::run();
?>

Phương thức trong interface có thể sử dụng đối số

<?php
interface OutputInterface
{
    public function load($arrayOfData);
}
class SerializedArrayOutput implements OutputInterface
{
    public function load($arrayOfData)
    {
        return serialize($arrayOfData);
    }
}
class JsonStringOutput implements OutputInterface
{
    public function load($arrayOfData)
    {
        return json_encode($arrayOfData);
    }
}
class ArrayOutput implements OutputInterface
{
    public function load($arrayOfData)
    {
        return $arrayOfData;
    }
}
 
$arrayOfData = array('interface', 'abstract class');
 
echo SerializedArrayOutput::load($arrayOfData);
echo '<br>';
echo JsonStringOutput::load($arrayOfData);
echo '<br>';
print_r(ArrayOutput::load($arrayOfData));
?>

Interface không phải là class nhưng nó cũng có tính kế thừa như class

<?php
interface MoveInterface
{
    public function run();
}
 
interface FlyInterface extends MoveInterface
{
    function fly();
}
class Person implements FlyInterface
{
    public function run()
    {
        echo 'Loài người đi bằng 2 chân<br>';
    }
 
    public function fly()
    {
        echo 'Loài người có thể di chuyển trên không trung bằng máy bay.';
    }
}
 
Person::run();
Person::fly();
?>

Điều này có nghĩa là nếu một đối tượng Person implements một giao diện FlyInterface thì nó phải khai báo thêm các phương thức của MoveInterface vì FlyInterface kế thừa giao diện MoveInterface.

Có thể dùng đồng thời interface và abstract class

<?php
interface MoveInterface
{
    function run();
}
interface EatInterface
{
    function eat();
}
abstract class ActiveAbstract{
    abstract function sing();
 
    public function playFootball(){
        echo 'Con người có thể chơi bóng bằng chân.<br>';
    }
}
 
class Person extends ActiveAbstract implements MoveInterface, EatInterface
{
    public function run ()
    {
        echo 'Con người đi bằng 2 chân<br>';
    }
 
    public function eat(){
        echo 'Con người là động vật ăn tạp<br>';
    }
 
    public function sing(){
        echo 'Con người có thể hát<br>';
    }
 
    public function playFootball(){
        Parent::playFootball();
        echo 'Con người cũng có thể chơi bóng bằng tay';
    }
}
 
Person::run();
Person::eat();
Person::sing();
Person::playFootball();
?>

Khi nào thì sử dụng interface, khi nào sử dụng abstract class

Khi một nhóm đối tượng có cùng bản chất kế thừa từ một class thì sử dụng abstract class.

Khi một nhóm đối tượng không có cùng bản chất nhưng chúng có hành động giống nhau thì sử dụng interface.

Để lại một trả lời

Hãy trở thành người đầu tiên bình luận!

Thông báo cho
avatar
wpDiscuz