Với những ai đã từng sử dụng lập trình hướng đối tượng trong ngôn ngữ khác, việc chuyển qua PHP rất dễ dàng. Trong phần lớn các trường hợp, những khái niệm cơ bản của lập trình hướng đối tượng đều được áp dụng trong PHP. Chỉ có duy nhất vài cú pháp đã được thay đổi cho phù hợp với tính chất đặc thù của ngôn ngữ nền web này. Một số kiến thức cơ bản sau giúp bạn học PHP có thể hiểu về lập trình hướng đối tượng trong PHP
Viết định nghĩa lớp
Để tạo một lớp ta dùng từ khóa class như sau:
Bạn có thể sử dụng bất kì tên class nào cũng được miễn là nó không phải từ khóa dành riêng cho các chức năng của PHP (echo, while, for, …). Như trong đoạn mã trên, bạn sẽ thêm vào những thuộc tính và phương thức vào phần thân của lớp (nằm giữa 2 dấu ngoặc nhọn). Thông thường, ta sẽ để tất cả các thuộc tính ở đầu class. Tuy nhiên, bạn cũng có thể không cần khai báo thuộc tính mà trực tiếp gán giá trị cho chúng khi cần. Mặc dù PHP cho phép thực hiện điều này nhưng tôi khuyên bạn không nên làm vì đây là thực hành tồi, rất có thể sẽ gây phiền phức cho bạn về sau.
Dưới đây là ví dụ mẫu về khai báo thuộc tính trong lớp.
Bạn có thể thấy trước tên thuộc tính có từ khóa public. Đây là từ khóa chỉ phạm vi truy cập của thuộc tính. Ở đây, public nghĩa là bất kì code nào bên ngoài cũng có thể truy cập vào thuộc tính $name và $age. Khi đó, chúng có thể được thay đổi bất kì lúc nào.
Thông thường, đây không phải là cách làm khôn ngoan. Theo nguyên tắc, bạn nên che giấu lớp của mình càng nhiều càng tốt. Do đó, để lộ những thuộc tính ra ngoài là điều không nên. Để làm được điều này, PHP cung cấp cho bạn thêm 2 từ khóa nữa: private và protected. Với private, code bên ngoài lớp không thể truy cập thuộc tính bên trong. Còn với protected, cũng giống như private, code bên ngoài không thể truy cập ngoại trừ trường hợp của lớp con.
Để gán giá trị cho các thuộc tính này, ta có 2 cách: một là thông qua hàm khởi tạo (constructor), hai là ta gán giá trị sau khi đã tạo một thể hiện (instance) của lớp thông qua một phương thức bên trong. Bạn cũng có thể gán giá trị mặc định cho thuộc tính nhưng nó chỉ có thể là giá trị đơn giản mà không cần tính toán như trong ví dụ sau:
Phương thức thể hiện những gì mà đối tượng có thể thực hiện được. Thực ra, phương thức chính là hàm (function) mà bạn đã quá quen thuộc. Về bản chất, nó hoạt động y như hàm, chỉ khác tên gọi mà thôi.
Cũng như thuộc tính, bạn có thể giới hạn mức truy cập cho phương thức bằng các từ khóa public, private và protected. Tuy nhiên, với phương thức, nếu bạn không dùng bất kì từ khóa nào như ví dụ ở trên thì mặc định nó sẽ có mức truy cập public. Ngoài ra, ta cũng có thể dùng từ khóa static để báo cho PHP biết rằng đây là phương thức có thể truy cập trực tiếp mà không cần phải tạo thể hiện.
Tới đây, tôi đoán bạn đang thắc mắc chỗ $this->name nghĩa là gì vì nó trông quái lạ. Khi tạo một lớp, ta thường có nhu cầu sử dụng các thuộc tính và phương thức trong lớp đó, và để làm điều này, ta phải truy xuất chúng thông qua một biến đặc biệt, được gọi là biến $this. Như ta thấy ở ví dụ ở trên, theo sau biến $this là kí hiệu mũi tên -> rồi đến tên thuộc tính mà ta đã khai báo.
Trước khi tiếp tục, bạn hãy lưu ý rằng dấu $ xuất hiện trước this chứ không phải trước name. Nếu bạn dùng câu lệnh $this->$name thì tùy theo ngữ cảnh, nó sẽ cho ra kết quả khác nhau mà không phải là giá trị của thuộc tính $name.
Ví dụ sau đây trình bày cách thức khai báo các thuộc tính và phương thức trong lớp. Lưu ý rằng ta sẽ đặt mức truy cập của tất cả thuộc tính là private để không cho phép thay đổi giá trị từ code bên ngoài. Thay vào đó, ta tạo một phương thức public để làm công việc này.
Bạn có thể thấy trong phương thức Deposit, tôi dùng câu điều kiện để kiếm tra giá trị của $amount để chắc rằng người dùng không nhập giá trị không hợp lệ có thể làm hỏng thuộc tính $balance (ví dụ người dùng nhập vào số âm cho $amount).
Trong trường hợp phương thức Deposit là static, bạn sẽ không thể sử dụng biến $this vì nó tham chiếu đến đối tượng hiện tại được tạo ra từ lớp Account. Còn phương thức static thì truy xuất trực tiếp mà không cần thông qua đối tượng nào.
Trong số các phương thức mà bạn sẽ viết trong lớp, PHP cung cấp cho bạn một số phương thức đặc biệt. Ở đây, tôi sẽ trình bày phương thức đặc biệt đầu tiên được gọi là phương thức khởi tạo (constructor). Phương thức này sẽ tự động chạy mỗi khi một đối tượng được tạo ra. Trong PHP, một lớp chỉ có thể có một constructor và nó không bắt buộc.
Phương thức khởi tạo được PHP gán cho một cái tên đặc biệt để nó biết đường mà chạy khi ta tạo đối tượng mới. Ví dụ dưới đây minh họa cho phương thức khởi tạo (lưu ý 2 dấu gạch dưới trước chữ construct).
Thông thường, nhiệm vụ chính của constructor là gán giá trị ban đầu cho các thuộc tính trong lớp. Ở ví dụ trên, khi đối tượng Account mới được tạo ra, thuộc tính $balance sẽ được gán giá trị ban đầu là 1000.
Lớp của bạn có thể có vô số thuộc tính và phương thức. Những phương thức này có thể đơn giản hay phức tạp là túy ý bạn. Tuy nhiên, mục đích chính của phương pháp lập trình hướng đối tượng là để giảm thiểu sự phức tạp và làm cho code của bạn dễ quản lý hơn. Do đó, bạn không nên nhồi nét tất cả mọi chức năng vào trong một phương thức. Thay vào đó, bạn nên tạo ra các phương thức nhỏ hơn với mỗi phương thức chỉ thực hiện duy nhất một chức năng. Khi cần thực hiện một chức năng nào đó, bạn chỉ cần gọi tên phương thức thực hiện chức năng đó ra.
Một trong những ưu điểm của lập trình hướng đối tượng chính là khả năng kế thừa. Một lớp có thể kế thừa những thuộc tính và phương thức từ một lớp khác và sử dụng chúng như thể chúng là của mình. Giả sử ta có lớp Person, lớp này có những đặc tính cơ bản của một người như tên, tuổi, giới tính. Sau đó, tôi tạo thêm 2 lớp Teacher và Student. Cả 2 lớp này tuy khác nhau về chức năng công việc nhưng đều có những đặc tính tương tự nhau trong lớp Person. Do đó, tôi sẽ cho 2 lớp này kế thừa từ lớp Person để thừa hưởng những đặc tính của nó mà không phải khai báo thủ công cho từng lớp.
Như ta thấy, để truy xuất phần tử của lớp cha, ta có thể dùng 2 cú pháp khác nhau. Một là dùng như thể nó là phần tử của lớp con, hai là gọi trực tiếp bằng từ khóa parent::. Đây là vấn đề sở thích cá nhân, bạn thích dùng cách nào thì tùy.
Nếu ở trong lớp con, bạn khai báo một phương thức có tên giống với tên phương thức trong lớp cha thì phương thức trong lớp con sẽ override phương thức đó trong lớp cha. Điều này có nghĩa là nếu bạn tạo một đối tượng từ lớp con, khi bạn gọi chạy phương thức đã được override, thì phiên bản trong lớp con sẽ được chạy thay vì lớp cha.
Lưu ý: nếu bạn override một phương thức trong lớp con, để gọi chạy phương thức đó ở lớp cha, bắt buộc bạn phải dùng cú pháp parent::. Nếu dùng cú pháp $this, bạn sẽ rơi vào vòng lặp hàm đệ quy vô tận.
Để ngăn chặn một phương thức có thể bị override trong lớp con, bạn dùng từ khóa final trong phiên bản ở lớp cha như sau:
Bạn cũng có thể dùng từ khóa final này để đặt trước từ khóa class để báo cho PHP biết rằng lớp đó không thể kế thừa.
Vậy là tôi đã trình bày tất cả những gì bạn cần biết để có thể khai báo định nghĩa lớp. Trong bài tiếp theo, tôi sẽ trình bày cách sử dụng lớp và các thủ thuật khi sử dụng chúng.
Không có nhận xét nào:
Đăng nhận xét