Hướng đối tượng luôn là một cái gì đó khiến mình và các bạn sinh viên trong trường rất là đau não vì không được trang bị kỹ càng về mặt kiến thức lẫn tính lười biếng và thụ động khi học môn này.
Hôm nay, mình sẽ tổng hợp lại về khái niệm này và đưa ra một vài ví dụ về lập trình hướng đối tượng với mong muốn lưu trữ cho bản thân một góc nhìn về OOP cũng như chia sẻ kiến thức tổng quát cho các bạn để các bạn có thể tự trả lời những câu hỏi sau :
- Hướng đối tượng là gì ?
- Tại sao sinh ra nó ?
- Ý nghĩa giữa cuộc sống và lập trình (hướng đối tượng).
Hướng Đối Tượng Là Gì ?
Hướng đối tượng đúng như tên của nó là hướng vào một đối tượng, nghĩa là nó có động cơ được xác định từ trước. Lập trình hướng đối tượng là kỹ thuật lập trình nhằm vào sự tương tác giữa các đối tượng.
Mỗi đối tượng (object) có những thuộc tính (property), những phương thức (method) xác định các chức năng của đối tượng. Bên cạnh đó, đối tượng cũng có khả năng phát sinh các sự kiện (event) khi thay đổi thông tin, thực hiện một chức năng hay khi đối tượng khác tác động vào. Tất cả những thuộc tính, phương thức và sự kiện tạo nên cấu trúc của đối tượng. Một ngôn ngữ được gọi là lập trình có tính hướng đối tượng phải đáp ứng được các tuyên ngôn sau ( mình tự gọi là tuyên ngôn hay khái niệm ) :
– Abstraction : tính trừu tượng.
– Encapsulation : tính đóng gói.
– Inheritance : tính kế thừa.
– Polymorphism : tính đa hình.
Mỗi tuyên ngôn đều có vai trò quan trọng trong lập trình hướng đối tượng.
1/- Tính Trừu Tượng (Abstraction)
Bạn thường lẫn lộn giữa lớp (Class) và đối tượng (Object). Cần phân biệt lớp là một khái niệm trừu tượng, còn đối tượng là một thể hiện cụ thể của lớp. Kiểu như 1 cái là Primary và 1 cái là Logical ( Ảo và hiện thực – vật lý ).
[notification type=\”alert-info\” close=\”true\” ]Ví dụ : bản thiết kế nhà là lớp, ngôi nhà được xây dựng dựa trên bản thiết kế là đối tượng. [/notification]
Sự trừu tượng có thể được hiểu đơn giản như sau:
Giả sử, kiến trúc để xây dựng 1 chiếc xe sẽ bao gồm: Bánh xe, yên xe, thắng.
Như vậy, những mô hình xe máy, xe đạp, xe hơi cũng được gọi là xe khi chúng thỏa mãn những yếu tố mà kiến trúc một chiếc xe quy định.
Diễn giải lại điều ở trên bằng hình ảnh để thấy rõ điều đó:
Qua biểu đồ này chúng ta thấy rằng, khi chiếc xe đạp, xe máy, xe hơi kế thừa mô hình xe. Nó sẽ phải định nghĩa 3 phương thức trừu tượng là banhxe(), yenxe(),thangxe(). Dù rằng ở mỗi thể loại xe đều có những đặc thù riêng biệt.
Như vậy có thể hiểu, mô hình trừu tượng trong thực tế được sử dụng để quản lý mô hình gốc. Nó định ra một quy định cơ bản, và yêu cầu bất kể một lớp nào, hoặc phương thức nào khi muốn làm việc với nó, thì buộc phải định nghĩa theo các quy tắc mà nó đã đặt ra. Nhằm đảm bảo tính nhất quán và dễ kiểm soát mã nguồn hơn đối với các dự án có quy mô lớn và phức tạp.
Tuy nhiên, vì lớp trừu tượng (abstract) vẫn được xem là một lớp. Thế nên, ngoài chức năng quy định lớp trừu tượng ra, thì nó vẫn có thể khởi tạo các thuộc tính (properties) hoặc phương thức( method ) khác để phục vụ cho việc sử dụng của những phương thức kế thừa nó.
Một ví dụ về việc sử dụng mô hình lớp trừu tượng:
<?php abstract class employee{ protected $empname; protected $empage; public function setdata($empname,$empage){ $this->empname = $empname; $this->empage = $empage; } abstract function outputData(); } class EmployeeData extends employee{ public function __construct($name,$age){ $this->setdata($name,$age); } function outputData(){ echo $this->empname; echo $this->empage; } } $a = new EmployeeData("Hitesh","24"); $a->outputData(); ?>
Từ những đối tượng giống nhau, bạn có thể trừu tượng hóa thành một lớp.
Tính trừu tượng cho phép bạn loại bỏ tính chất phức tạp của đối tượng bằng cách chỉ đưa ra các thuộc tính và phương thức cần thiết của đối tượng trong lập trình.
Tham khảo thêm:
- Có mấy loại phần mềm máy tính hiện nay và quan trọng nhất
- Chức năng chính của Microsoft Word trên máy tính của bạn
2/- Tính Đóng Gói (Encapsulation)
Mỗi lớp được xây dựng để thực hiện một nhóm chức năng đặc trưng riêng của lớp, trong trường hợp một đối tượng thuộc lớp cần thực hiện một chức năng không nằm trong khả năng vì chức năng đó thuộc về một đối tượng thuộc lớp khác, thì nó sẽ yêu cầu đối tượng đó đảm nhận thực hiện công việc.
Một điểm quan trọng trong cách giao tiếp giữa các đối tượng là một đối tượng sẽ không được truy xuất trực tiếp vào thành phần dữ liệu của đối tượng khác cũng như không đưa thành phần dữ liệu của mình cho đối tượng khác một cách trực tiếp. Tất cả mọi thao tác truy xuất vào thành phần dữ liệu từ đối tượng này qua đối tượng khác phải được thực hiện bởi các phương thức (method) của chính đối tượng chứa dữ liệu. Đây cũng chính là một tính chất quan trọng trong lập trình hướng đối tượng gọi là tính đóng gói (encapsulation) dữ liệu.
Tính đóng gói cho phép dấu thông tin của đối tượng bằng cách kết hợp thông tin và các phương thức liên quan đến thông tin trong đối tượng.
[notification type=\”alert-info\” close=\”true\” ]
Ví dụ :
Xe hơi có các chức năng (phương thức phô diễn bên ngoài) như Ngừng, Chạy tới, Chạy lùi. Đây là những gì cần thiết cho Tài xế tương tác với Xe hơi. Xe hơi có thể có một đối tượng Động cơ nhưng Tài xế không cần phải quan tâm. Tất cả những gì cần quan tâm là những chức năng để có thể vận hành xe. Do đó, khi thay một Động cơ khác, Tài xế vẫn sử dụng các chức năng cũ để vận hành Xe hơi , các chức năng (phương thức) đưa ra bên ngoài (Interface) không bị thay đổi.
[/notification]
3/- Tính Kế Thừa
Tính kế thừa là khả năng cho phép ta xây dựng một lớp mới dựa trên các định nghĩa của một lớp đã có. Lớp đã có gọi là lớp Cha, lớp mới phát sinh gọi là lớp Con và đương nhiên kế thừa tất cả các thành phần của lớp Cha, có thể mở rộng công năng các thành phần kế thừa cũng như bổ sung thêm các thành phần mới.
Bạn phân biệt hai loại quan hệ :
Là – một ( is – any )
Biểu thị tính kế thừa. Trong quan hệ \”là – một\”, một đối tượng của lớp Con được xem như là một đối tượng của lớp Cha.
Lớp kế thừa
[notification type=\”alert-info\” close=\”false\” ]
Ví dụ :
Từ lớp Xe bạn tạo nên lớp Xe hơi mở rộng, lớp này mặc nhiên kế thừa tất cả các thành phần của lớp xe. Bạn có thể nói một xe hơi là một chiếc xe.
[/notification]
Có – một
Quan hệ này mang ý nghĩa gồm có. Trong quan hệ \”có – một\”, một đối tượng có thể có một hoặc nhiều thành phần tham chiếu đến các đối tượng khác.
[notification type=\”alert-info\” close=\”false\” ]
Ví dụ :
Trong mô hình xe hơi, bạn muốn diễn tả ý tưởng chiếc xe \”có – một\” tay lái. Bạn không thể phát sinh lớp Xe hơi từ một Tay lái hay ngược lại (một Xe hơi là một Tay lái). Thay vì vậy, bạn phải có hai lớp độc lập làm việc với nhau trong đó, lớp phía ngoài (lớp Xe hơi) sẽ tạo và đưa ra công năng của lớp phía trong (lớp Tay lái).
[/notification]
4/- Tính Đa Hình
Thể hiện thông qua việc gửi các thông điệp (message). Việc gửi các thông điệp này có thể so sánh như việc gọi các hàm bên trong của một đối tượng. Các phương thức dùng trả lời cho một thông điệp sẽ tùy theo đối tượng mà thông điệp đó được gửi tới sẽ có phản ứng khác nhau. Người lập trình có thể định nghĩa một đặc tính (chẳng hạn thông qua tên của các phương thức) cho một loạt các đối tượng gần nhau nhưng khi thi hành thì dùng cùng một tên gọi mà sự thi hành của mỗi đối tượng sẽ tự động xảy ra tương ứng theo đặc tính của từng đối tượng mà không bị nhầm lẫn.
Thí dụ khi định nghĩa hai đối tượng \”hinh_vuong\” và \”hinh_tron\” thì có một phương thức chung là \”chu_vi\”. Khi gọi phương thức này thì nếu đối tượng là \”hinh_vuong\” nó sẽ tính theo công thức khác với khi đối tượng là \”hinh_tron\”.
Kết nối trễ – Late Binding
Là khả năng cho phép người lập trình gọi trước một phương thức của đối tượng, tuy chưa xác định đối tượng có phương thức muốn gọi hay không. Đến khi thực hiện, chương trình mới xác định được đối tượng và gọi phương thức tương ứng của đối tượng đó. Kết nối trễ giúp chương trình được uyển chuyển hơn, chỉ yêu cầu đối tượng cung cấp đúng phương thức cần thiết là đủ.
[notification type=\”alert-info\” close=\”false\” ]
Ví dụ :
Bạn có lớp Xe với phương thức Chạy và các lớp Xe đạp, Xe hơi, Xe đẩy cùng phát sinh từ lớp Xe. Bạn chưa biết sẽ sử dụng xe gì đề di chuyển vì tùy thuộc tình hình có sẵn xe nào nên gọi trước phương thức Chạy. Khi chương trình thực thi, tùy theo đối tượng của lớp nào được đưa ra mà phương thức Chạy của đối tượng đó được gọi.
[/notification]
Nạp chồng – Overloading
Đây là khả năng cho phép một lớp có nhiều thuộc tính, phương thức cùng tên nhưng với các tham số khác nhau về loại cũng như về số lượng. Khi được gọi, dựa vào tham số truyền vào, phương thức tương ứng sẽ được thực hiện.
Ghi chồng – Overriding
Hình thức này áp dụng cho lớp Con đối với lớp Cha. Lớp Con được phép có một phương thức cùng tên, cùng số tham số có kiểu dữ liệu như phương thức của lớp Cha hoặc những lớp trước đó nữa (lớp phát sinh ra lớp Cha …) với cài đặt khác đi. Lúc thực thi, nếu lớp Con không có phương thức riêng, phương thức của lớp Cha sẽ được gọi, ngược lại nếu có, phương thức của lớp Con được gọi.
Lưu ý là trong javascript gốc, không có tinh overloading bạn nhé. Thực tế là họ phải fake nó đi, làm một bước trung gian vì bản chất javascript là một ngôn ngữ kịch bản kiểu tuyến tính. Nó giống như đời thường mình vậy nên mình rất hứng thú với nó.
Tham khảo thêm:
- Phân biệt lập trình hướng đối tượng và lập trình hướng cấu trúc
- Các đặc tính cơ bản của lập trình hướng đối tượng
- 5 ngôn ngữ lập trình hướng đối tượng phổ biến nhất
Tại Sao Sinh Ra Nó ?
Khi bạn đọc đến dòng này rồi thì chắc bạn cũng đã hiểu, ta không thể lập trình một cái gì đó lớn hơn và rộng hơn nếu ta không sử dụng OOP trong dự án của chúng ta. Đúng vậy, Lập trình Hướng đối tượng được sinh ra giúp ta lập trình vững chắc từng bước một và dễ dàng chia sẻ nhiệm vụ cho mỗi người trong một đội nhóm, dễ dàng bảo trì hệ thống. Đem lại sự yên tâm khi build và sự rõ ràng khi tìm lỗi. Nói chung, nếu bạn áp dụng OOP vào dự án của bạn, bạn sẽ ngủ ngon hơn và có thời gian đi chơi với Gấu mà không bị đau đầu.
Ý Nghĩa Giữa Cuộc Sống Và Lập Trình (Hướng Đối Tượng)
Liên tưởng từ lập trình trong máy tính ra lập trình trong cuộc sống. Có rất nhiều điểm tương đồng.
Trong cuộc sống hàng ngày, ta có thể làm những điều ta muốn một cách tuyến tính hay một cách có hệ thống. Đó là tùy ở bạn. Khi bạn lên một plan cụ thể, tức là bạn làm cho cuộc sống của bạn có mục tiêu, đối tượng rõ ràng. Cuộc sống của bạn ví như một hệ thống lớn mà nếu bạn design theo cảm tính ngay từ đầu mà không đặt ra những mục tiếu rõ ràng ( hướng đối tượng) bạn sẽ gặt lại những thứ không rõ ràng. Đến một lúc nào đó, bạn sẽ không kiểm soát được cuộc đời mình nữa và tương lai bạn sẽ nằm lại trong bàn tay người khác.
Chính vậy, hãy áp dụng hướng đối tượng vào cuộc sống chỉ với những tuyên ngôn căn bản nhất :
– Abstraction : tính trừu tượng.
– Encapsulation : tính đóng gói.
– Inheritance : tính kế thừa.
– Polymorphism : tính đa hình.
Bạn có thể trừu tượng hóa những kết quả của bạn thông qua những mô hình hay làm những việc nhỏ hơn có hệ thống giống như môi trường thật để có thể thử sai hay gọi là test. Trong máy tính họ gọi là Unit Testing.
Bạn có thể vẻ ra một bản kế hoạch chi tiết và biết được mình đang có những gì, và thiếu những gì để từng bước kết nối với những người ta cần để có thể kéo họ và với ta, giúp ta trong dự án của riêng mình hoặc thuê họ. Trong xã hội thật, người ta gọi đó là OutSourcing.
Trên đường đời bạn đi, luôn có những người thầy, trong kế hoạch của bạn luôn có những công việc giống nhau. Việc của bạn là làm thế nào để tối giản các bước giống nhau đó. Bạn có thể học cách quản lý công việc, thời gian từ những người thầy trên đường đời. Kế thừa từ họ, từ những phần căn bản nhất để rồi mở rộng ( extend) ra với nhiều loại hình khác nhau ( polymorphism) dù cùng chung một nguồn ( source ). Ví dụ, bạn mở quán cafe, bạn cần người quản lý, bạn cần nhiều cộng sự nhưng làm sao bạn biết bạn cần. Đầu tiên nhất, bạn cần người dẫn đường. Bạn kế thừa kinh nghiệm của người này, mở rộng ra và áp dụng vô trường hợp của bạn và thế là bạn đã tạo ra một hệ thống của riêng bạn.
Thuật ngữ OOP rất hay. Trong nghành IT, mình đã được học nhiều thứ và luôn tìm hiểu tận gốc để có thể hiểu được người nghĩ ra thuật ngữ muốn nói gì và áp dụng vào cuộc sống của riêng mình.
Hãy tự thiết kế cuộc đời mình – LifeStyle Design.
Kết Bài
Hy vọng, bài viết ví dụ về lập trình hướng đối tượng trên đây sẽ giúp ích cho các bạn trong quá trình học tập. Chúc các bạn học tập thật tốt!