01/10/2018, 15:35

Bài 25: PHP – OOP Step By Step (part 2)

………………… Step 12: Truy cập trực tiếp các thuộc tính – đừng làm điều này! Bạn không cần phải dùng phương thức để truy cập các thuộc tính đối tượng. Bạn có thể lấy trực tiếp bằng cách sử dụng toán tử (->) và tên của biến. Ví ...

…………………

Step 12:

Truy cập trực tiếp các thuộc tính – đừng làm điều này!

Bạn không cần phải dùng phương thức để truy cập các thuộc tính đối tượng.

Bạn có thể lấy trực tiếp bằng cách sử dụng toán tử (->) và tên của biến.

Ví dụ: với thuộc tính $name (trong đối tượng $ku_tin) bạn có thể lấy giá trị của nó như sau:

$name =  $ku_tin->name;

Mặc dù là có thể làm được, nhưng sẽ không tốt để làm như thế bởi vì nó có thể gặp rắc rối, rắc rối chổ nào? Có thể có nhiều hệ lụy và một trong số đó chính là phạm vi của biến. Bạn thử nghĩ xem một ngày đẹp trời biến đó bị tác giả nâng cấp nó lên thành biến private hoặc protected thì bên ngoài làm sao mà bạn gọi nó trực tiếp được.

Bạn nên sử dụng phương thức get để lấy nó.

<?php include(“class_lib.php”); ?>                   

<?php

            $ku_tin = new person();                      

            $ken = new person;

            $ku_tin->set_name(“Tran Ku Tin”);

            $ken->set_name(“Do Su Ken”);          

            // truy cập trực tiếp thuộc tính là không nên.

            echo “Ku Tin’s full name: “.$ku_tin->name;

?>

 

Step 13

Constructors

Tất cả các đối tượng có thể có một phương thức xây dựng đặc biệt gọi là “contructor”. Contructor cho bạn khởi tạo các giá trị thuộc tính của đối tượng, một khi đối tượng được khởi tạo (đối tượng được instance of).

Lưu ý: Nếu bạn tạo một hàm __contruct(), PHP sẽ tự động gọi hàm __contruct() khi bạn khởi tạo một đối tượng từ class của bạn.

Phương thức ‘contruct’ bắt đầu với 2 dấu gạch dưới (__) và có từ ‘contruct’.

<?php             

            class person {

                        var $name;

                        function __construct($persons_name) {            

                                    $this->name = $persons_name;           

                        }                     

                        function set_name($new_name) {

                                     $this->name = $new_name;

                        }         

                        function get_name() {               

                                     return $this->name;                 

                         }                    

            }                    

?>

À chắc do thói quen nên tôi hay sợ mọi người không hiểu tôi cũng dùng từ hàm, biến, phương thức,thuộc tính thay đổi qua lại. Từ giây phút này khi nhắc đến hướng đối tượng là ta sẽ dùng đúng từ của nó luôn nhé:

  • Functions = methods
  • Variables = properties

Step 14:

Tạo một đối tượng với contructor

Hiện tại chúng ta đã tạo một phương thức contructor, chúng ta có thể cung cấp một giá trị cho thuộc tính $name khi chúng ta khởi tạo đối tượng person.

EX:

$ku_tin = new person(“Tran Ku Tin”);

Điều này sẽ tiết kiệm cho chúng ta gọi phương thức set_name(), giảm số lượng code. Contructor hầu như dùng thường trong PHP và Java…

<?php include(“class_lib.php”); ?>                   

<?php

            $ku_tin = new person(“Tran Ku Tin”);

            echo “Ku Tin’s full name: “.$ku_tin->get_name();

?>

Step 15:

Giới hạn khả năng truy cập thuộc tính.

Một trong số nguyên tắc đóng gói trong OOP là giới hạn truy cập các thuộc tính và phương thức bằng việc sử dụng 3 keyword, cái này theo chuyên ngành người ta gọi là “access modifiers”:

  1. public
  2. private
  3. protected

‘Public’ là mặc định nếu bạn khai báo phương thức và thuộc tính mà không chỉ rõ thì mặc định thuộc tính/phương thức đó sẽ ngầm hiểu là public.

<?php             

            class person {              

            var $name;                  

                        public $height;             

                        protected $social_insurance;

                        private $pinn_number;

                        function __construct($persons_name) {            

                                    $this->name = $persons_name;           

                        }                     

                        function set_name($new_name) {         

                                    $this->name = $new_name;

                        }         

                        function get_name() {

                                    return $this->name;

                        }                     

            }

?>

Lưu ý: Khi bạn khai báo một thuộc tính với từ khóa ‘var’ thì nó được xem như ‘public’.

Step 16:

Tiếp việc giới hạn truy cập: part 2

Khi bạn khai báo một thuộc tính là ‘private’, thì nó chỉ được truy cập trong class, nơi khai báo nó mà thôi.

Khi một thuộc tính được khai báo là ‘protected’, thì nó sẽ được truy cập nơi class khai báo nó và class dẩn xuất (class dẩn xuất là class kế thừa, class con, bước kế tiếp là bạn sẽ biết cái này).

Thuộc tính được khai báo là ‘public’ nó không bị giới hạn truy cập.

Để giúp bạn hiểu cái này tôi làm ví dụ sau , bạn có thể chạy nó và đọc comment trong ví dụ luôn nhé.

<?php include(“class_lib.php”); ?>

<?php 

            $ku_tin = new person(“Tran Ku Tin”);  

            echo “Ku Tin’s full name: ” .  $ku_tin->get_name() ; 

            /* 

            Khi $pinn_number được khai báo là private, Dòng code sau sẽ tạo ra một lổi. 

            */ 

            echo “Ku Tin pinn number: “.$ku_tin->pinn_number; 

?>

Lưu ý: Nếu bạn cố gắng truy cập thuộc tính private bên ngoài class bạn sẽ được ban tặng thông báo:

‘Fatal error: Cannot access private property person::$pinn_number in …’

Step 17:

Giới hạn truy cập các phương thức

Giống các thuộc tính, bạn có thể điều khiển truy cập tới các phương thức bằng cách sử dụng 3 keyword: public, protected, private.

<?php

            class person { 

                        var $name; 

                        public $height; 

                        protected $social_insurance; 

                        private $pinn_number;

                        function __construct($persons_name){  

                           $this->name = $persons_name; 

                        }      

                        private function get_pinn_number(){

                                    return $this->pinn_number; 

                        }      

            }  

?>

Lưu ý: phương thức get_pinn_number() là private thì chỉ nơi tạo ra nó mới truy cập được nó, hay nói dể hiểu là trong class khai báo nó. Nếu trong trang PHP index của bạn muốn gọi nó thì bạn phải khai báo nó lại thành public.

Step 18:

Inheritance – kế thừa.

Inheritance là một cấu trúc căn bản trong OOP nơi bạn có thể sử dụng một class như lớp cơ sở, lớp cha cho các lớp khác.

Tại sao làm nó?

Làm điều này sẽ cho bạn khả năng tái sử dụng code trong lớp cha.

Bạn muốn tạo một class ‘employee’ và chúng ta nhận thấy rằng class ‘employee’ có kiểu như ‘person’, chúng sẽ chia sẽ các thuộc tính/phương thức chung.

Trong trường này kế thừa sẽ giúp bạn sử dụng lại code trong 2 class khác nhau:

// ‘extends’ là keyword dùng để  inheritance class khác

class employee extends person

{

            function __construct($employee_name) {

                        $this->set_name($employee_name);

            }

}

Step 19 :

Sử dụng lại code với inheritance : part 2

Bởi vì class ‘employee’ dựa vào class ‘person’. ‘employee’ tự động có tất cả các phương thức và thuộc tính public, protected của ‘person’.

Bạn cũng có thể nói rằng ‘employee’ là một kiểu của person.

class employee extends person

{

            function __construct($employee_name){

                        $this->set_name($employee_name);

            }

}

Để ý chúng ta có thể sử dụng set_name() trong ‘employee’, mặc dù chúng ta không khai báo phương thức này trong ‘employee’ class. Đó là bởi vì chúng ta đã tạo set_name() trong class ‘person’.

Class ‘person’ được gọi là lớp cha, lớp cơ sở (base class, parent class), class employee gọi là class con, class dẩn xuất (class derive).

Step 20:

Sử dụng lại code với inheritance: part 3

Như bạn có thể thấy trong code dưới, chúng ta gọi get_name trong đối tượng ‘employee’.

<?phpinclude(“class_lib.php”); ?>

            <?php

                        // Using our PHP objects in our PHP pages.

                        $ku_tin = new person(“Tran Ku Tin”);

                        echo “Ku Tin’s full name: ” . $ku_tin->get_name();

                        $ken = new employee(“Do Su Ken”);

                        echo “—> ” . $ken->get_name();

            ?>

Đây là ví dụ ‘’Có thể làm giảm dòng code trong OOP (không phải ghi lại các phương thức giống nhau 2 lần , Don’t Repeat Yourself (DRY)) ‘’ trong khi vẩn giữ và đặt mục đích code chúng ta và dể bảo trì hơn.

Step 21 :

Overriding methods

Đôi khi (khi sử dụng interitance), bạn có thể cần thay đổi cách làm việc của các phương thức lớp cha.

Lấy ví dụ, phương thức set_name()  trong class ‘employee’, phải làm cái gì đó khác hơn là những gì nó làm trong class cha, class person.

Bạn ‘override’ ghi đè phương thức set_name() của person, bằng cách khai báo cùng tên phương thức trong ‘employee’.

<?php

            class person

            {

                        protected function set_name($new_name) {

                                    if ($new_name != “Bin Bin”) {

                                                $this->name = strtoupper($new_name);

                                    }

                        }

            }

            class employee extends person

            {

                        protected function set_name($new_name) {

                                    if ($new_name == “Tran Ku Tin”) {

                                                $this->name = $new_name;

                                    }

                        }

            }

?

Vậy hàm set_name() trong ‘employee’ là khác nhau với set_name() phiên bản trong ‘person’.

Step 22:

Overriding methods : part 2

Đôi khi bạn có thể cần truy cập các phương thức từ lớp cơ bản trong việc ghi đè của class con.

Trong ví dụ sau, chúng ta override phương thức set_name() thực hiện trong class ‘employee’.

Chúng ta sử dụng code này: person::set_name($new_name); để truy cập phương thức  của lớp cha.

<?php

            class person

            {

                        // explicitly adding class properties are optional – but

                        // is good practice

                        var $name;      

                        function __construct($persons_name) {

                                    $this->name = $persons_name;

                         }

                         public function get_name() {

                                    return $this->name;

                         }

                         // protected methods and properties restrict access to

                         // those elements.

                         protected function set_name($new_name) {

                                     if ($this->name !=  “Bin Bin”) {

                                                $this->name = strtoupper($new_name);

                                     }

                        }

            }

            // ‘extends’ để kế thừa class khác

            class employee extends person

            {

                        protected function set_name($new_name) {

                        if ($new_name ==  “Tran Ku Tin”) {

                                    $this->name = $new_name;

                        }

                        else if ($new_name ==  “Obama”) {

                                    person::set_name($new_name);

                        }

            }

            function __construct($employee_name)

            {

                        $this->set_name($employee_name);

            }

}

?>

Lưu ý: sử dụng ký hiệu :: cho bạn dùng trực tiếp tên của class để truy cập các thuộc tính và phương thức của nó.

‘person::set_name()’ //nói cho PHP tìm set_name() trong class person.

Cũng có một đường khác nếu bạn muốn tham chiếu tới class cha hiện hành bằng cách sử dụng keyword ‘parent’

protected function set_name($new_name)

{         

            if ($new_name ==  “Tran Ku Tin”) {

                        $this->name = $new_name;     

             }        

             else if ($new_name ==  “Obama”) {

                        parent::set_name($new_name);

            }         

}

Có khi nào bạn nghĩ là, sao phải override, không thích cái hàm của class cha thì tạo hàm khác mà dùng, cớ sao rắc rối vậy? Oh là bởi vì nó muốn giữ hướng đối tượng, bạn thử nghĩ lớp cha định nghĩa hàm là đôi mắt và có lẻ nó định nghĩa chưa đầy đủ lắm, nên lớp nhân viên (‘employee’) muốn có đôi mắt khác hơn, nhưng hok lẻ nó phải tìm cái tên khác để đặt, đặt hột nhãn hay sao, kakaka. Do vậy mới có khái niệm override.

Kết Luận:

Chúng ta đã chạm vào các vấn đề cơ bản của OO PHP. Nhưng bạn nên cảm thấy thoải mái để sang vấn đề khác khi đã thấu hiểu OOP.

Cách tốt nhất là hãy ghi code và chạy nó.

Tôi đề nghị tạo 10 đối tượng đơn giản và làm cái j đó cũng giản đơn, sau đó sử dụng các đối tượng này trong trang PHP. Một khi bạn đã làm điều đó, bạn sẽ cảm thấy thoải mái với các đối tượng.

Nếu bạn thấy thú vị thì hãy cho tôi biết !

0