Bài 39: Các mức truy cập private protected và public

Ngày đăng: 2024-04-14 15:02:50

Mục lục:

 1. Mức truy cập private

  2. Mức truy cập protected

  3. Mức truy cập public 

  4. Khai báo tên, thuộc tính để nhận dạng mức truy cập

  5. Hàm Set và hàm Get các thuộc tính

  6. Khi nào sử dụng cấp độ truy cập private

  7. Khi nào sử dụng cấp độ truy cập protected

  8. Khi nào sử dụng cấp độ truy cập public

 

1. Mức truy cập private

Đây là thành phần chỉ dành riêng cho nội bộ của lớp, nghĩa là ta không thể truy xuất tới thành phần private ở lớp con hoặc ở bên ngoài lớp.

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

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

Ví dụ 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

 

Ở ví dụ trên muốn truy xuất giá trị thuộc tính loaixe thì phải thông qua phương thức setLoaixe và getLoaixe chứ không thể trỏ thẳng trực tiếp đến thuộc tính loaixe vì thuộc tính loaixe đang ở mức private.

Như bài này là sai:

 

// 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

// nhưng sai tại vì loaixe đang ở mức private

// nên không thể truy xuất bên ngoài

$xe->loaixe = 'Wave S';

  

// Lấy giá trị thuộc tính loại xe

// cũng sai vì loaixe là private

echo $xe->loaixe;


Ví dụ 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();

 

Phần ghi chú tôi đã giải thích rõ rồi nên tôi không giải thích gì thêm.

2. Mức truy cập protected

Mức truy cập protected chỉ cho phép truy xuất nội bộ trong lớp đó và lớp kế thừa, riêng ở bên ngoài lớp sẽ không truy xuất đc. Mức protected thường được 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 (overwrite).

Ví dụ:

 

// Lớp Xe

class Xe

{

    protected $loaixe;

}

  

// Kế thừa từ lớp xe

class XeHonda extends Xe

{

    function hienThiThongTin()

    {

        // Lệnh này đúng vì loaixe đang ở

        // mức protected nên nó được kế thừa

        $this->loaixe = 'Wave S';

    }

    protected function suaChuaXe()

    {

        // Lệnh

    }

}

  

// ------------------//

// Chuong Trình Chính//

// ------------------//

  

$honda = new XeHonda();

  

// Lệnh này sai vì loaixe đang

// ở mức protected nên ở bên ngoài lớp

// không được truy xuất vào

$honda->loaixe = 'Wave Tàu';

  

// Lệnh này đúng

$honda->hienThiThongTin();

  

// Lệnh này sai vì: function suaChuaXe đang

// ở mức protected nên ko thể truy xuất

// từ ngoài lớp XeHonDa

$honda->suaChuaXe();

 

3. Mức truy cập public

Đây là mức truy cập thoáng nhất bởi vì bạn có thể truy cập tới các phương thức và thuộc tính ở bất cứ đâu, dù trong nộ bộ của lớp hay ở lớp con hay cả bên ngoài lớp đều được.

Khi khai báo thuộc tính là public ta có thể dùng từ khóa var để thay thế cho public như những ví dụ các bài 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

}


Khi khai báo với hàm là public nếu ta không đặt từ public ở đầu thì php sẽ tự hiểu hàm này là public.

 

Ví dụ:

 

class Xe

{

    // Ở dạng public vì ta không có từ khóa gì ở trước

    function showTenXe()

    {

        // lệnh

    }

  

    // Ở dạng public vì có từ khóa public ở trước

    public function showHangXe()

    {

        // lệnh

    }

  

    // Ở dạng private vì có từ khóa private ở trước

    private function setTenxe()

    {

        // lệnh

    }

  

    // Ở dạng protected vì có từ khóa protected ở trước

    protected function getTenXe()

    {

        // lệnh

    }

}

4. Khai báo tên thuộc tính để nhận dạng cấp độ truy cập

Cái tiêu đề nghe hơi lại nhưng nó thực sự rất hữu ích trong quá trình làm team cho các bạn đó. Nếu trong một team có những quy ước đặt tên biến, tên hàm riêng thì nhìn vào dòng code tuy nhiều người nhưng tưởng chừng như là chỉ có một người làm duy nhất. Bởi vậy mình đặt ra tiêu đều này để hướng dẫn các bạn cách đặt tên biến, tên hàm trong một lớp. Tuy nhiên không phải người nào cũng áp dụng như vậy nên các bạn đừng chém nhé, các bạn đọc nhưng có quyền không làm theo.

Cách chọn từ đặt cho tên biến và tên hàm

Thông thường tên biến (thuộc tính) phải là một danh từ hoặc tình từ, còn tên của hàm (phương thức) bắt đầu bằng một động từ.

 

class A

{

    public $username;

    public $password;

  

    public function getUsername()

    {

  

    }

  

    public function getPassword()

    {

  

    }

  

    public function checkLogin()

    {

  

    }

}

 

Khai báo tên biến dạng private

Thông thường nếu biến ở dạng private thì tên biến các bạn nên đặt hai dấu gạch dưới rồi mới đến tên biến.

Ví dụ:

class A

{

    private $__private;

    private function __func_private()

    {

    }

}

 

Khai báo tên biến dạng protected

Thông thường nếu ở dạng protected thì các bạn nên đặt một dấu gạch dưới rồi mới tới tên biến

Ví dụ:

// Lớp A

class A

{

    protected $_protected;

    protected function _func_protected()

    {

    }

}

 

Khai báo tên biến dạng public

Nếu ở dạng này bạn chỉ cần khai báo tên bình thường

 

class A

{

    public  $public;

    public function func_public()

    {

    }

}

 

5. Hàm Set và hàm Get các thuộc tính

Các thuộc tính trong đối tượng thường có hai thao tác là gán dữ liệu và lấy dữ liệu. Có những thuộc tính ta muốn khi gán giá trị hoặc khi lấy giá trị thì sẽ có một đoạn code tác động vào. Ví dụ như tôi muốn khi thiết lập mật khẩu cho người dùng thì mật khẩu sẽ được tự động thêm một số ký tự đặc biệt và mã hóa md5 để an toàn và bảo mật hơn, như vậy mỗi lần gán giá trị cho thuộc tính mật khẩu tôi phải thêm một đoạn như thế này:

 

class A

{

    public $username;

    public $password;

}

  

$a = new A();

$a->password = md5('thehalfheart' . 'ky_tu_muon_them');

 

Giả sử trong quá trình lập trình tôi có sử dụng phép gán này 100 lần thì đôi lúc sẽ bị nhầm lẫn ký tự thêm vào, chưa tính đến chuyện sau này tôi muốn sửa ký tự thêm vào thành một chuỗi khác hoặc sử dụng hàm mã hóa khác thì tôi phải vào 100 dòng code đó để sửa. 

Giả sử tôi muốn khi lấy giá trị của thuộc tính username thì kết quả trả về sẽ có thêm một đoạn là "Xin Chào + Username", như vậy mỗi lần tôi lấy giá trị username phải bổ sung chữ xin chào vào. Có 100 dòng code thì phải thực hiện thao tác này 100 lần, điều này thật là phiền toái.

Qua những lý do đó tôi nghĩ có giải pháp là ta tạo những hàm SET và GET dùng cho việc gán và lấy dữ liệu cho các thuộc tính username và password để sau này nếu thay đổi thì chỉ cần vào hai hàm này sửa là được.

Quy tắc đặt tên cho Get và Set như sau: setThuoctinh()getThuoctinh().

Ví dụ:

 

class A

{

    private $__username;

    private $__password;

  

    function getUsername()

    {

        return 'Xin chào ' . $this->__username;

    }

  

    function setUsername($username)

    {

        $this->__username = $username;

    }

  

    function getPassword()

    {

        return $this->__password;

    }

  

    function setPassword($password)

    {

        $this->__password = md5($password.'ky_tu_muon_them');

    }

}

  

// Sử dụng

$a = new A();

  

$a->setUsername('TheHalfheart');

  

echo $a->getUsername();

  

$a->setPassword('matkhau');

  

echo $a->getPassword();

 

6. Khi nào sử dụng cấp độ truy cập private

Thông thường để an toàn dữ liệu các thuộc tính đều ở dạng private, nhưng điều này rất phiền vì ta phải tạo thêm các hàm SET và GET nên các lập trình viên cũng ít khi sử dụng private. Tuy nhiên có những trường hợp sau ta bắt buộc phải dùng ở dạng private để an toàn cho đối tượng.

  • Những thuộc tính có tính biến đổi dữ liệu khi nhập và lấy dữ liệu như hai ví dụ về Username và Password ở trên.
  • Những phương thức chỉ dùng trong nội bộ trong lớp đó, không có sử dụng bên ngoài lớp.

Đó là 2 đặc điểm cơ bản để bạn chọn độ truy cập là private.

7. Khi nào sử dụng cấp độ truy cập protected

Protected thường được dùng khi bạn biết chắc là có lớp khác sẽ kế thừa lớp này và những phương thức, thuộc tính đó chỉ được dùng trong lớp kế thừa nó.

Giả sử bạn khai báo lớp Động Vật, trong đó có hàm lưu dữ liệu động vật vào database, hàm này dùng chung cho tất cả các lớp con kế thừa lớp Động Vật. Và để bảo mật nên tôi không muốn ở bên ngoài lớp có thể sử dụng được, vì vậy tôi khai báo là protected.

Đó là những ví dụ cơ bản, chứ thực tế thì cũng tùy vào từng bài toán cụ thể mà bạn lựa chọn

8. Khi nào sử dụng cấp độ truy cập public

Public là cấp độ thoáng nhất, nó có thể gọi ở mọi nơi từ trong nội bộ của lớp đến lớp kế thừa nó, thậm chí cả bên ngoài lớp cũng gọi được.

Những hàm được khai báo public thường được dùng để lấy dữ liệu và xuất dữ liệu ra bên ngoài, hoặc là những hàm mang tính chất là hàm thao tác cuối cùng với người coder. Ví dụ như các hàm SET và GET được để ở dạng public.

 

Về bài trước...

                                Bài tiếp theo...

 

 


Tài liệu lập trình PHP

Bài viết trong cùng chuyên mục

Góc games giải trí (chơi trực tiếp trên web) Đăng nhập (chơi có thưởng)



Cờ caro


Butterfly


Lật hình (luyện trí nhớ)

Cờ tướng ONLINE

Xếp hình

Ghép hình

15_PUZZLE

Kill ghosts

Banchim

Planet Defense

Tower game

Bắn bóng

Plapy Bird (NH.Đông)

Vượt chướng ngại vật

Vẽ hình cứu người

Game Phases

Game vui chơi có thưởng

Game bắn cá



0379136392

Thông tin liên hệ: Lê Văn Thuyên - ĐT: 0379136392 ; Gmail: lethuyen0379136392@gmail.com

Comment

 +   Lê Văn Thuyên-0379136392:Cảm ơn quý vị và các bạn đã vào Website của Lê Thuyên! Lê thuyên rất mong nhận được sự góp ý của quý vị và các bạn cho sự phát triển của website này. Xin chân thành cảm ơn!

Trả lời

 *   Dũng Trung-090567448:Lê Văn Thuyên0379136392--->Ok.Anh!

Trả lời

 *   Bé Nguyễn-benguyen@gmail,com:Lê Văn Thuyên0379136392--->Good job!

Trả lời

 +   -:

Trả lời

 +   -:

Trả lời

8409