Hướng dẫn dùng abstraction meme trong PHP

1. Lớp trừu tượng abstract

Nếu bạn đã từng học qua lập trình hướng đối tượng một ngôn ngữ bất kỳ khác như C++, Java thì abstract khá quen thuộc, và trong php đây cũng là một tính chất của lập trình hướng đối tượng nhưng nó không được xếp vào tính chất quan trọng, tính chất này giống như tính kế thừa theo tầm nhìn bề ngoài. Lớp Abstract sẽ định nghĩa các hàm (phương thức) mà từ đó các lớp con sẽ kế thừa nó và Overwrite lại (tính đa hình). Tất cả các phương thức của lớp abstract đều phải được khai báo là abstract và phải ở mức protected và public, không được ở mức private. Lớp Abstract có thể có thuộc tính nhưng thuộc tính không được khai báo là abstract, và bạn không thể khởi tạo một biến của lớp Abstract được.

Hướng dẫn dùng abstraction meme trong PHP

Hướng dẫn dùng abstraction meme trong PHP

Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

Để khai báo một lớp Abstract ta dùng cú pháp sau:

abstract class BaseClass
{
    // phương thức ở mức protected
    abstract protected function hello();
 
    // Phương thức ở mức public
    abstract public function hi();
}

Trong lớp Abstract các phương thức bạn khai báo ở dạng Abstract đều phải tuân theo cú pháp trên, tức là bạn không được định nghĩa thêm dòng lệnh nào bên trong nó. Như ví dụ dưới này là sai.

abstract class BaseClass
{
    // Phương thức này sai vì hàm hello là
    // hàm abstract nên không được code bên trong nó
    abstract protected function hello()
    {
        // dòng code
        echo 1;
    }
 
}

Như tôi nói ở trên bạn không thể tạo một biến đối tượng mới của lớp Abstract, như ví dụ dưới này là sai:

abstract class BaseClass
{
    abstract protected function hello();
}
 
// Sai vì BaseClass là lớp Abstract nên không
// khởi tạo mới được
$base = new BaseClass();

Mức truy cập các hàm của Abstract phải ở public hoặc protected để lớp kế thừa có thể định nghĩa lại và các thuộc tính của lớp Abstract không được khai báo Abstract. Các bạn xem ví dụ dưới đây:

abstract class BaseClass
{
    // Đúng
    public $name;
 
    // Sai vì các thuộc tính không được để ở dạng abstract
    abstract public $title;
 
    // Đúng
    abstract protected function hello();
 
    // Sai vì hàm abstract không thể ở private
    abstract private function hi_there();
}

Lớp kế thừa từ lớp Abstracth phải Rewrite lại tất cả các hàm Abstract trong lớp Abstract, nếu không sẽ bị báo sai. Ví dụ:

abstract class Person
{
    protected $ten;
    protected $cmnd;
    protected $namsinh;
 
    abstract public function showInfo();
}
 
// Lớp này sai vì chưa viết lại hàm showInfo
class CongNhan extends Person
{
 
}
 
// Lớp này đúng vì ta đã khai báo, viết lại
// đầy đủ các hàm abstract
class SinhVien extends Person
{
    public function showInfo(){
 
    }
}

2. Hàm và lớp final

Lớp Final là lớp được khai báo là lớp cuối cùng, không một lớp nào có thể kế thừa nó. Tương tự như hàm Final trong Abstract hoặc trong kế thừa chỉ để gọi sử dụng, không được viết lại (Override).  Để dễ hình dung các bạn xem ví dụ sau đây và thông qua phần ghi chú tôi đã giải thích.
Ví dụ lớp final:

// Lớp Filnal
final class Person
{
    protected $ten;
    protected $cmnd;
    protected $namsinh;
    public function showInfo()
    {
        echo 'freetuts.net';
    }
}
 
// Hàm này sẽ bị báo lỗi vì lớp SinhVien
// đã kế thừa một lớp Final, điều này là không thể
class SinhVien extends Person {
}
 
// Đoạn code này đúng vì lớp Final được
// sử dụng bình thường như các lớp khác
// chỉ có điều là không được kế thừa
$person = new Person;
$person->showInfo();

Ví dụ hàm final:

class Person
{
    protected $ten;
    protected $cmnd;
    protected $namsinh;
    final public function showInfo()
    {
        echo 'freetuts.net';
    }
}
 
// Lớp này đúng vì lớp Person không phải
// là một lớp final
class SinhVien extends Person {
 
    // Hàm này sai vì hàm showInfo
    // là hàm final trong lớp Person
    // nên không thể Override lại
    public function showInfo(){
 
    }
 
    public function Go()
    {
        // Đoạn code này đúng vì hàm final được
        // sử dụng bình thường
        $this->showInfo();
    }
}

3. Lời kết

Trong bài này chúng ta đã tìm hiểu được thế nào là lớp Abstract (lớp trừu tượng) và từ khóa Final trong php. Qua bài này tôi hy vọng các bạn hiểu được bốn tính chất của lập trình hướng đối tượng mà bất kỳ một ngôn ngữ nào khác đều phải tuân theo quy luật này. Nếu bạn thấy một ngôn ngữ nào mà không có đầy đủ bốn tính chất này thì ngôn ngữ đó không phải là ngôn ngữ có hỗ trợ lập trình hướng đối tượng (như Javascript). Bài tiếp theo chúng ta sẽ tìm hiểu Interface Trong PHP

Hướng dẫn dùng abstraction meme trong PHP

Published May 21st, 2018 1:38 p.m. 6 min read

Giới thiệu

Nội dung

Đầu tiên chúng ta sẻ tìm hiểu khái niệm của chúng

1. Abstract Class là gì ?

  • Lớp trừu tượng đơn giản được xem như một class cha cho tất cả các Class có cùng bản chất.

  • Do đó mỗi lớp dẫn xuất (lớp con) chỉ có thể kế thừa từ một lớp trừu tượng bằng từ khóa extends.

  • Lớp con kế thừa từ lớp trừu tượng có thể override các phương thức trừu tượng trong đó.

  • Lớp trừu tượng có thể khai báo các thuộc tính và các phương thức bình thường và không có thuộc tính trừu tượng (lớp trừu tượng không cho phép khởi tạo tham số, chỉ khai báo mà thôi).

  • Bên cạnh đó nó không cho phép tạo instance, nghĩa là sẽ không thể tạo được các đối tượng thuộc lớp đó. Ví dụ Animal là 1 class trừu tượng thì không thể khai báo : $animal = new Animal

  • Các phương thức được định nghĩa là abstract trong abstract class thì chỉ khai báo tên hàm và không viết nội dung hàm trong đó. Nội dung sẻ được viết trong class kế thừa khi override lại phương thức đó.

Mình có 1 cái ví dụ đơn giản như thế này.

2. Interface là gì ?

  • Interface không phải là 1 lớp. Nó được mô tả như là 1 bản thiết kế cho các class có chung cách thức hoạt động.
  • Vì không phải là 1 lớp nên 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.
  • Các phương thức chỉ khai báo tên hàm và không viết nội dung hàm trong đó.
  • Không có khái niệm phạm vi của phương thức, tất cả đều là public.
  • Lớp con kế thừa từ interface sẻ 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 bằng từ khóa implements

Mình củng có ví dụ đơn giản về interface.

Khi nào dùng interface và khi nào dùng Abstract Class.

Đọc xong cái đống trên kia chắc bạn đang tự hỏi. Vậy Abstract và Interface có cách dùng khá giống nhau. Vậy tại sao phải tạo ra 2 cái làm gì ?

Hướng dẫn dùng abstraction meme trong PHP
.

  • Nhìn chung abstract class và interface đều được coi như 1 "bản thiết kế" cho các class con kế thừa nó.

Vì sao lại gọi là "bản thiết kế"?

  • Gọi là "bản thiết kế" vì ví dụ như trong 1 dự án, bạn muốn ép buộc người lập trình phải tuân thủ theo một số các phương thức và các phương thức này đã được định nghĩa sẵn những thứ cơ bản, để giúp cho lập trình viên có thể kế thừa các phương thức này và phát triển lớp con của họ. Thì bạn phải tạo ra các abstract class hoặc interface và liệt kê các phương thức cần thiết trong đó. Do đó abstract class và interface chỉ chứa các khai báo mà không quan tâm bên trong các hàm thực hiện những gì.

Abstract Class là "bản thiết kế" cho Class:

  • Về bản chất thì abstract class là 1 class nên nó có thể khai báo thêm các thuộc tính và phương thức khác không phải trừu tượng. Nó được xem như "bản thiết kế" cho class vì những class extends lại từ nó ngoài override lại các phương thức trừu tượng của nó thì còn có thể sử dụng các thuộc tính của nó.
  • Trong ví dụ abstract class ở trên, 2 class kế thừa abstract class Animal đều có cùng bản chất là động vật. Chúng có thể sử dụng được biến $name trong abstract class Animal.

Interface là "bản thiết kế" cho Method:

  • Interface không phải là class nên chỉ dùng để khai báo các phương thức. Nó được xem như "bản thiết kế" cho method vì những class implements lại nó đều phải override lại các phương thức của nó.
  • Trong ví dụ interface ở trên, 2 class kế thừa từ interface Move không có cùng bản chất. 1 class thuộc động vật và 1 class thuộc phương tiện đi lại. Nhưng chúng có chung hành động là run().

Kết luận

Sau khi đọc bài này hy vọng các bạn sẻ hiểu hơn về abstract class và interface. Bài viết khá nhiều chữ nên chắc dể gây nhàm chán nhưng tổng kết lại chỉ có 1 số ý sau:

  • Abstract thường được sử dụng trong trường hợp các class kế thừa từ nó có cùng bản chất (thuộc 1 nhóm đối tượng)
  • Interface thường được sử dụng trong trường hợp các class kế thừa không có cùng bản chất (nhóm đối tượng) nhưng chúng có thể thực hiện các hành động giống nhau.

All Rights Reserved