Lập trình Hướng đối tượng-PHP [Phần 1]
Giới thiệu
Vạn vật quanh chúng ta đang vận động không ngừng…Ngày ngày mặt trời vẫn mọc ở đằng Đông, rồi mặt trời lặn đằng Tây và mặt trăng cũng lên =)) ( có vẻ đi hơi xa rồi) .Tuy nhiên đơn thuần khi ta quan sát vạn vật tự nhiên, lập trình hướng đối tượng như một cách quan sát các đối tượng như thế. Rồi cố gắng nắm bắt những hành động cùng đặc tính của chúng và biểu diễn dưới dạng đối tượng ảo trong ngôn ngữ lập trình và triển khai một phần mềm bởi sử dụng các đối tượng khác nhau. Hướng đối tượng được áp dụng vào nhiều ngôn ngữ lập trình khác nhau đáng chú ý như: Java, C++, C#, Python, PHP, Ruby,… Bài này chúng ta cùng tìm hiểu về OOP và xem nó được thể hiện vào PHP như thế nào nhé
Lập trình hướng đối tượng là gì?
OOP viết tắt của Object-Oriented Programming – Lập trình hướng đối tượng ra đời giải quyết các vấn đề mà lập trình truyền thống gặp phải. Lập trình hướng đối tượng không chỉ đơn giản là các cú pháp, câu lệnh mới mà còn là một cách tư duy mới khi giải quyết 1 vấn đề. Thực tế khi làm một việc gì đó, chúng ta sẽ quan tâm đến hai điều: vật bị tác động và hành động. Với lập trình cũng vậy, nếu chúng ta tập trung vào hành động thì đó là lập trình hướng thủ tục còn nếu tập trung vào các vật thể thì đó là lập trình hướng đối tượng. Với cả hai cách giải quyết vấn đề, đều cho chúng ta một kết quả như nhau, chỉ có một điều khác nhau là cách chúng ta tập trung vào cái gì?

Ưu điểm của lập trình hướng đối tượng
Vì lập trình hướng đối tượng ra đời sau nên nó khắc phục được tất cả các điểm yếu của các phương pháp lập trình trước đó. Cụ thể nó các ưu điểm sau:
- Dễ dàng quản lý code khi có sự thay đổi chương trình.
- Dễ mở rộng dự án.
- Tiết kiệm được tài nguyên đáng kể cho hệ thống.
- Có tính bảo mật cao.
- Có tính tái sử dụng cao.
Một số khái niệm cơ bản trong lập trình hướng đối tượng
Đối tượng
Trong lập trình hướng đối tượng, đối tượng được hiểu như là 1 thực thể: người, vật hoặc 1 bảng dữ liệu, . . .
Một đối tượng bao gồm 2 thông tin: thuộc tính và phương thức.
- Thuộc tính chính là những thông tin, đặc điểm của đối tượng. Ví dụ: một người sẽ có họ tên, ngày sinh, màu da, kiểu tóc, . . .
- Phương thức là những thao tác, hành động mà đối tượng đó có thể thực hiện. Ví dụ: một người sẽ có thể thực hiện hành động nói, đi, ăn, uống, . . .
Lớp
Các đối tượng có các đặc tính tương tự nhau được gom lại thành 1 lớp đối tượng.
Bên trong lớp cũng có 2 thành phần chính đó là thuộc tính và phương thức.
Sự khác nhau giữa đối tượng và lớp
Lớp là một khuôn mẫu còn đối tượng là một thể hiện cụ thể dựa trên khuôn mẫu đó.
Để dễ hiểu hơn mình sẽ lấy một ví dụ thực tế:
- Nói về con mèo thì lớp chính là loài mèo. Loài mèo có:
- Các thông tin, đặc điểm như 4 chân, 2 mắt, có đuôi, có chiều cao, có cân nặng, màu lông . . .
- Các hành động như: kêu meo meo, đi, ăn, ngủ, . . .
- Như vậy mọi động vật thuộc loài mèo sẽ có những đặc điểm như trên.
- Đối tượng chính là một con mèo cụ thể nào đó như con mèo con đang nằm dưới chân mình.
Một ví dụ khác. Ví dụ này mình sẽ dùng 1 hình ảnh để minh hoạ:
/B01_T%E1%BB%95ng%20quan%20v%E1%BB%81%20l%E1%BA%ADp%20tr%C3%ACnh%20OOP/1_T%E1%BB%95ng%20quan%20v%E1%BB%81%20l%E1%BA%ADp%20tr%C3%ACnh%20h%C6%B0%E1%BB%9Bng%20%C4%91%E1%BB%91i%20t%C6%B0%E1%BB%A3ng_Howkteam_com.png)
- Bạn thấy đấy khi nói đến xe otô thì lớp chính khuôn mẫu của cái xe với các đặc trưng như có 4 bánh và có thiết kế tương tự như hình vẽ. Đối tượng chính là các chiếc xe otô cụ thể như Toyota camry, Honda city, Ford ranger.
Sự xuất hiện của 2 khái niệm mới là lớp và đối tượng chính là đặc trưng của phương pháp lập trình hướng đối tượng. Nó đã giải quyết được các khuyết điểm của phương pháp lập trình hướng cấu trúc để lại. Ngoài ra 2 khái niệm này đã giúp biểu diễn tốt hơn thế giới thực trên máy tính.
Các đặc điểm cơ bản của lập trình hướng đối tượng.Ứng dụng trong PHP
Trong lập trình hướng đối tượng, sẽ có 4 tính chất sau:
Tính trừu tượng (abstraction)
Trong lập trình hướng đối tượng giúp giảm sự phức tạp thông qua việc tập trung vào các đặc điểm trọng yếu hơn là đi sâu vào chi tiết.
- Ví dụ khi một lập trình viên tạo một lớp (class) dùng đại diên cho các tài khoản tiền gửi ngân hàng của các khách hàng và đặt tên cho lớp này là BankAccount. Lớp này có hai thuộc tính là $balance và $interest dùng để lưu dữ liệu số tiền dư và lãi suất tiền gửi của tài khoản.
class BankAccount { public $balance; public $interest; }
- Tiếp theo lập trình viên này thêm các phương thức gửi tiền (deposit) và rút tiền (withdraw) :
class BankAccount { public $balance; public $interest; public function deposit ($amount) { //code } public function withdraw ($amount) { //code } }
Với tính trừu tượng (abstraction) thì toàn bộ sự phức tạp của việc xử lý quá trình gửi tiền và rút tiền sẽ được thực hiện trong 2 phương thức deposit và withdraw. Các lập trình viên không cần phải quan tâm tới sự phức tạp (hay nội dung chi tiết) của việc xử lý các công việc gửi tiền và rút tiền trên mà chỉ cần biết mục đích của từng phương thức là gì.
//nap tien vao tai khoan public function deposit ($amount) { if ($amount < 50000) { //so tien toi thieu return "Error! The minumun amount is 50"; } if ($amount > 100000000) { //tai khoan nay cho phep ban nap toi da 100 trieu 1 lan return "Error! You exceed the maximum amount, please upgrade your account"; } $balance += $amount // tang so du tai khoan }
Vậy với tính trừu tượng thì lập trình viên chỉ cần quan tâm tới mục đích của phương thức deposit là để nạp tiền vào tài khoản. Toàn bộ chi tiết của quy trình xử lý gửi tiền sẽ được thực hiện ở bên trong phương thức deposit.
Tính kế thừa (Inheritance)

Con người | Lập trình viên |
Thuộc tính: Mắt, mũi, miệng,… | Thuộc tính: Mắt, mũi, miệng, bằng cấp, chứng chỉ,… |
Phương thức: Ăn, ngủ, chơi game,… | Phương thức: Ăn, ngủ, chơi game,… |
Nhìn vào bảng trên ta thấy 2 đối tượng Con người và Lập trình viên có những đặc điểm chung và riêng. Ta có thể thấy rằng Lập trình viên có thể kế thừa nhưng đặc điểm và phương thức của Con người. Hình trên sẽ được viết lại dưới dạng kế thừa như sau:
// Lớp Cha class Person { // Thuộc Tính var $mat = ''; var $mui = ''; var $mieng = ''; // Hàm, phương thức function eat(){ // lệnh } function sleep(){ // lệnh } function playGame(){ // lệnh } } // Lớp Con class Programmer extends Person { // Tất cả các thuộc tính khác đều kế thừa từ cha // nên không cần viết lại // chỉ riêng thuộc tính này là cha ko có nên ta phải khai báo var $qualifications = ''; var $certificate = ''; // Tất cả các hàm, phương thức đều kế thừa từ cha // nên không cần viết lại }
Tính đa hình
Tính đa hình có thể nói luôn tồn tại song song với tính kế thừa. Khi có nhiều lớp con kế thừa lớp cha nhưng có những tính chất khác nhau cũng gọi là đa hình, hoặc những tác vụ trong cùng một đối tượng được thể hiện nhiều cách khác nhau cũng gọi là đa hình. Tính đa hình là kết quả tất yếu khi ta phát triển khả năng kế thừa và nâng cấp chương trình.
Ví dụ: trong hình học tứ giác, hình thang có 3 lớp con là hình thang cân, hình thang vuông và hình bình hành. Vì 3 hình này có vài tính chất riêng biệt nên có thể gọi là tính đa hình.

Đó là sự đa hình trong thực tế, còn đa hình trong lập trình thì được hiểu là Lớp Con sẽ viết lại những phương thức ở lớp cha (ovewrite).Các class cùng implement một interface nhưng chúng có cách thức thực hiện khác nhau cho các method của interface đó.
<?php /** * */ class Animal { // thuoc tinh var $mat = ''; var $mui = ''; var $chan = ''; function an() { //code } function ngu() { //code } } /** * */ class Bird extends Animal { var $canh = ''; public $mat = 'toi co mot doi mat'; function bay() { // } } $animal = new Animal(); echo $animal->mat; //ket qua : '' $bird = new Bird(); echo $bird->mat; // ket qua : toi co mot doi mat
Tính đóng gói
Tính đóng gói nhằm bảo vệ đối tượng không bị truy cập từ code bên ngoài vào để thay để giá trị các thuộc tính hay có thể truy cập trực tiếp. Việc cho phép truy cập các giá trị của đối tượng tùy theo sự đồng ý của người viết ra lớp của đối tượng đó.
Trong tính đóng gói có 2 ý chính:
- Các dữ liệu và phương thức có liên quan với nhau được đóng gói thành các lớp để tiện cho việc quản lý và sử dụng. Điều này được thể hiện qua cách ta xây dựng 1 class.
- Đóng gói còn để che giấu một số thông tin và chi tiết cài đặt nội bộ để bên ngoài không thể nhìn thấy. Điều này được thể hiện qua các phạm vi truy cập đã trình bày ở trên. Cụ thể:
- Các thuộc tính thường sẽ có phạm vi là private. Vì đây chính là các thông tin nội bộ của lớp không thể để truy cập 1 cách tuỳ tiện được (che giấu thông tin).
- Các phương thức thường sẽ có phạm vi là public. Vì đây chính là các hành vi (thao tác) mà lớp hỗ trợ cho chúng ta thực hiện những công việc nhất định nên cần phải cho phép mọi người có thể sử dụng được.
Một ví dụ thực tế về tính đóng gói. Nhà sản xuất chế tạo ra 1 smartphone họ phải đóng gói che giấu đi những mạch điện tử bên trong và chỉ để lộ ra màn hình, khe sạc, cắm tai nghe để giao tiếp.
/B03_Ca%CC%81c%20loa%CC%A3i%20pha%CC%A3m%20vi%20truy%20c%C3%A2%CC%A3p%20L%C3%A2%CC%A3p%20tri%CC%80nh%20OOP/2_Ca%CC%81c%20loa%CC%A3i%20pha%CC%A3m%20vi%20truy%20c%C3%A2%CC%A3p%20trong%20L%C3%A2%CC%A3p%20tri%CC%80nh%20h%C6%B0%C6%A1%CC%81ng%20%C4%91%C3%B4%CC%81i%20t%C6%B0%C6%A1%CC%A3ng_Howkteam_com.png)
Các mức truy cập:
- Public: Cho phép truy cập và sử dụng đến các phương thức cũng như thuộc tính ở phạm vi trong, ngoài class và nó hỗ trợ sự kế thừa.
- Private: Chỉ cho phép truy cập và sử dụng đến các phương thức cũng như thuộc tính ở phạm vi trong class.
- Protected:Cho phép truy cập và sử dụng đến các phương thức cũng như thuộc tính ở phạm vi trong class và nó hỗ trợ sự kế thừa.
Tính chất này đảm bảo sự bảo mật, toàn vẹn của đối tượng