1. Giới thiệu về phạm vi trong hướng đối tượng

Trong lập trình hướng đối tượng, các thuộc tính và phương thức được rằng buộc về mức độ truy cập, giúp dữ liệu được bảo mật hơn. Tất cả thuộc tính và phương thức của lớp cha đều sử dụng được ở lớp con, nhưng nếu có thuộc tính và phương thức ở lớp cha không muốn cho lớp con sử dụng hay ở lớp con có những thuộc tính và phương thức chỉ muốn sử dụng riêng trong lớp mà ta không được truy xuất ở ngoài lớp. Để giải được những vấn đề này ta sẽ có 3 phạm vi truy cập: public, protected, private. Trong đó:

  • Public : thuộc tính hoặc phương thức có thể truy cập từ mọi nơi, đây là mặc định.
  • Private: thuộc tính hoặc phương thức chỉ có thể truy cập trong lớp
  • Protected : thuộc tính và phương thức chỉ có thể truy cập trong lớp và bới các lớp dẫn xuất từ lớp đó.

Ta sẽ đi cụ thể vào từng phạm vi một cho dễ hiểu nhé!

2. Private trong hướng đối tượng PHP

Đây là giới hạn hẹp nhất của thuộc tính và phương thức trong hướng đối tượng. Nó chỉ dành riêng cho nội bộ của lớp và không thể truy xuất tới thành phần private ở lớp con hoặc ở bên ngoài lớp. Nói một cách cụ thể hơn là với giới hạn này thì các thuộc tính và phương thức này chỉ có thể sử dụng trong class của nó. Bên ngoài class không thể nào có thể sử dụng được nó kể cả lớp kế thừa nó cũng không sử dụng được.

Mức truy cập private thường được sử dụng với:

  • Thuộc tính dữ liệu nhằm bảo vệ dữ liệu nhằm bảo vệ chúng, tránh truy cập tự do từ bên ngoài. Ta sẽ có hàm SET và GET để lấy dữ liệu và gán dữ liệu.
  • Các phương thức trung gian mà ta tính toán trong nội bộ của đối tượng mà ta không muốn bên ngoài có thể can thiệp vào.

Ví dụ:

class Person
{
    //khai báo thuộc tính name ở private
    private $name;

    //Khai báo phương thức run ở private
    private function run()
    {
        return 'Đây là hàm run';
    }
}

//Khởi tạo class
$person = new Person();
//gọi phương thức name
$person->name;

Các bạn hãy thử chạy và nhận quả lỗi siêu to khổng lồ nhé!

Và mình sẽ đưa ra ví dụ về tính kế thừa và không kế thừa nhé! Các bạn sẽ được học ở bài sau và mình chỉ giới thiệu trước thôi.

  • Không kế thừa:
// Lớp Xe
class Xe
{
    private $loaixe;
  
    function getLoaixe()
    {
         return $this->loaixe;
    }
  
    function setLoaixe($loaixe)
    {
            $this->loaixe = $loaixe;
    }
}
  
// Khởi tạo một lớp đối tượng xe
$xe = new Xe();
  
// Gán giá trị cho thuộc tính loại xe
$xe->setLoaixe('Wave S');
  
// Lấy giá trị thuộc tính loại xe
echo $xe->getLoaixe();  // kết quả xuất ra Wave S
  • Có kế thừa:
// Lớp Xe
class Xe
{
    private $loaixe;
  
    var $tenxe;
  
    function getLoaixe()
    {
        return $this->loaixe;
    }
  
    function setLoaixe($loaixe)
    {
        $this->loaixe = $loaixe;
    }
  
    private function xoaLoaixe()
    {
        echo 'Hàm xóa loại xe';
    }
}
  
// Kế thừa từ lớp xe
class XeHonda extends Xe
{
    function hienThiThongTin()
    {
        // lệnh này đúng
        echo $this->tenxe;
  
        // lệnh này sai vì thuộc tính loaixe là
        // private trong lớp cha
        echo $this->loaixe;
  
        // lệnh này đúng
        $this->setLoaixe('Wave S');
  
        // lệnh này đúng
        echo $this->getLoaixe();
  
        /// Lệnh này sai vì hàm xoaLoaixe là
        // private trong lớp cha
        $this->xoaLoaixe();
    }
}
  
// -------------------
// Chương trình chính//
// -------------------
  
// Khởi Tạo mới lớp xe hon da
$xehonda = new XeHonda();
  
// Gọi hàm hienThiThongTin trong lớp XeHonda
// Các bạn kiểm tra trong hàm này để xem các
// lỗi mà tôi đã ghi chú
$xehonda->hienThiThongTin();
  
// Lệnh này đúng vì lớp XeHonda kế thừa lớp Xe nên
// nó được kế thừa các thuộc tính và hàm của lớp cha
$xehonda->setLoaixe('Suzuki');
echo $xehonda->getLoaixe();
  
// Lệnh này sai vì hàm xoaLoaixe trong lớp Xe là
// private nên lớp XeHonda không được kế thừa
$xehonda->xoaLoaixe();

3. Protected trong hướng đối tượng PHP

Khác với private, mức truy cập protected chỉ cho phép truy xuất nội bộ trong nó và kế thừa. Tức là các phương thức và thuộc tính khi khai báo chúng được sử dụng trong class đó và class con kế thừa của nó cũng có thể sử dụng được. Bên ngoài class thì sẽ không sử dụng được. Protected thường được sử dụng cho những phương thức và thuộc tính có khả năng bị lớp con định nghĩa lại.

Ví dụ:

class Person
{
    //khai báo thuộc tính xe dạng protected
    protected $name;
}

class Male extends Person
{
    function setName($name)
    {
        //đúng vì sử dụng trong class con
        $this->name = $name;
    }

    function getName()
    {
        //đúng vì sử dụng trong class con
        return $this->name;
    }
}

//khởi tạo lớp Person
$person = new Person();
//Sai vì biến name có visibility là protec nên không tác động từ ngoài class vào được
$person->name;
//khởi tạo lớp Male
$male = new Male();
//tác động vào biến name qua hàm setName
$male->setName(‘lập trình từ đầu);
echo $male->getName();

4. Public trong hướng đối tượng PHP

Đây là mức truy cập có mức độ truy cập rộng nhất và thoáng nhất vì ta có thể truy cập thuộc tính ở bất cứ đâu, dù ở trong hay ở ngoài hay lớp con đều được. Thông thường khi khai báo chương trình sẽ tự nhận là public nhưng ta nên khai báo từ khóa này vào thay vì bỏ trống. Khi khai báo từ khóa bằng public ta cũng có thể dùng từ khóa var để thay cho public như những ví dụ trước.

Ví dụ:

class Xe
{
    private $loaixe; // Mức private
    protected $tenxe; // Mức protected
    var $sokhung; // Mức public
    public $soseri; // Mức public
}
Hoặc:
class Person
{
    //khai báo thuộc tính xe dạng protected
    public $name;

    function setName($name)
    {
        //đúng vì sử dụng trong class con
        $this->name = $name;
    }

    function getName()
    {
        //đúng vì sử dụng trong class con
        return $this->name;
    }
}

//khởi tạo lớp Person
$person = new Person();
//tác động vào thuộc tính name
$person->name = 'Vũ Van A';
//tác động vào biến name qua hàm setName
$person->setName('Lập trình từ đầu');
echo $person->getName();