Typescript — Cuộc phiêu lưu với OOP (Phần 1)

Lê Xuân Quỳnh
5 min readOct 4, 2018

--

Nhắc đến lập trình hướng đối tượng (OOP) có 4 tính chất đặc thù mà bất kỳ developer nào cũng phải nắm rõ như “khẩu quyết tâm pháp”. Mặc dù được đưa vào môn học cơ bản trong trường đại học, nhưng khi được hỏi thì mình thấy đa phần các bạn sinh viên mới ra trường thường hay mơ hồ và có cái hiểu chưa đúng về lập trình OOP. Ở series này, mình sẽ cùng các bạn trên hành trình tìm về những khái niệm xưa cũ nhưng trên một ngôn ngữ mới toanh Typescript. Series sẽ gồm 4 phần cũng tương ứng với 4 tính chất đặc thù trong OOP

1. Tính trừu tượng (abstraction)
2. Tính đóng gói (encapsulation)
3. Tính đa hình (polymorphism)
4. Tính kế thừa (inheritance)

Vũ khí đầu tiên Abstraction

  1. Vũ khí đầu tiên, abstraction ?

Nghe đến abstraction hay trừu tượng bạn nghĩ ngay đến một cái gì đó không có thực, không tồn tại đúng không nào?

Thực ra thì trong OOP có tồn tại một lớp gọi là lớp trừu tưởng, nó hoàn toàn có thực. Nó trừu tượng ở chỗ, nó không thể dùng để tạo ra một thể hiện (instance) như những lớp bình thường khác. Lớp tượng này bạn có thể hiểu nó chỉ là một bộ bộ khung để bạn có thể tạo ra các lớp con của nó.

Ngoài ra các bạn cũng nên biết qua về khái niệm hàn lâm của nó, đừng thấy phức tạp quá mà bỏ qua nhé, cứ nghiền ngẫm rồi một ngày sẽ lĩnh hội thôi (nguồn wikipedia)

Tính trừu tượng (abstraction): Đây là khả năng của chương trình bỏ qua hay không chú ý đến một số khía cạnh của thông tin mà nó đang trực tiếp làm việc lên, nghĩa là nó có khả năng tập trung vào những cốt lõi cần thiết. Mỗi đối tượng phục vụ như là một “động tử” có thể hoàn tất các công việc một cách nội bộ, báo cáo, thay đổi trạng thái của nó và liên lạc với các đối tượng khác mà không cần cho biết làm cách nào đối tượng tiến hành được các thao tác. Tính chất này thường được gọi là sự trừu tượng của dữ liệu.
Tính trừu tượng còn thể hiện qua việc một đối tượng ban đầu có thể có một số đặc điểm chung cho nhiều đối tượng khác như là sự mở rộng của nó nhưng bản thân đối tượng ban đầu này có thể không có các biện pháp thi hành. Tính trừu tượng này thường được xác định trong khái niệm gọi là lớp trừu tượng hay lớp cơ sở trừu tượng.

Đến đây là thấy đủ “trừu tượng” rồi heng, chúng ta hãy cùng xem đối với Typescript chúng ta sẽ khai báo một lớp trừu tượng như thế nào nhé.

2. Typescript sử dụng nó như thế nào?

Để thể hiện được tính chất “trừu tưởng”, Typescript đã sử dụng Abstract classInterface để sử dụng được tính chất này.

Đến nay mặc dù OOP đã rất phổ biến nhưng đa số developer vẫn còn khá mơ hồ về việc phân biệt hai khái niệm Abstract classInterface, đây cũng là sợi dây thừng mà các các nhà tuyển dụng thường xuyên tròng vào cổ các bạn (nói chơi thôi nha ahihi). Nhưng tạm bỏ qua vấn đề này, chúng ta hãy đi thẳng đến cách làm thế nào để khai vào một Abstract class và một Interface nhé.

Abstract classes

Từ khóa để khai báo một lớp trừu tượng là “abstract class”, các phương thức muốn là trừu tượng thì sử dụng từ khỏa “abstract” trước tên hàm.

Interface

Từ khóa để khai báo một interface là “interface”, các phương thức không thể định nghĩa code xử lý. Lớp thực thi có thể implement nhiều interface cùng lúc.

Đến đây thì chúng ta cũng nhận ra một số sự khác biệt giữa 2 thể hiện của tính đối tượng trong OOP là Abstract Class và Interface. Sự khác nhau giữa chúng đó chính là mục đích sử dụng:

  • Abstract class: là một class cha cho tất cả các class có cùng bản chất. Bản chất ở đây được hiểu là kiểu, loại, nhiệm vụ của class. Hai class cùng hiện thực một interface có thể hoàn toàn khác nhau về bản chất.
  • Interface: là một chức năng mà bạn có thể thêm và bất kì class nào. Từ chức năng ở đây không đồng nghĩa với phương thức (hoặc hàm). Interface có thể bao gồm nhiều hàm/phương thức và tất cả chúng cùng phục vụ cho một chức năng.

Điểm lại một số đặc trưng của cả 2:

So sánh giữa Interface và Abstract Class

Nói tóm lại, việc khai báo một Abstract class hay một Interface khá đơn giản, nhưng mục đích thực sự của “Trừu tượng” này là gì? chúng ta hãy cùng đến với mục tiếp theo.

3. Món vũ khí này khi nào thì sài? tại sao nên sài nó?

Khái niệm đăng sau tính trừu tượng là chúng ta đang che dấu đi sự phức tạp của việc triển khai từ các lớp kế thừa mà chỉ cần quan tâm đến những Interface của chúng. Nếu vẫn còn khó hiểu hãy theo dõi ví dụ dưới đây.

Dễ dàng nhận thấy rằng superman được tham chiếu tới interface IWarrior, lúc này chúng ta sẽ không cần quan tâm superman sẽ là Siêu Anh Hùng hay là một Siêu Chiến Binh, chúng ta chỉ cần quan tâm interface IWarrior có 2 thuộc tính là name weapon cùng với 2 phương thức sayHi() arm(). Mọi chuyện đã trở nên vô cùng đơn giản.

Trong thực tế, bạn có thể bắt gặp tính trừu tượng ở đâu đó khi sử dụng các gói thư viện của bên thứ 3 (third-party). Khi bạn extends hoặc implements các Class hoặc Interface của họ, bỗng dưng hệ thống báo lỗi và bắt bạn phải override một phương thức nào của lớp đó, thì chắc chắn bạn sẽ hiểu ngay lớp đó chính là lớp trừu tượng. Như ví dụ dưới đây.

4. Tạm kết

Vậy đấy, chúng ta vừa mới biết về 1 trong 4 thứ vũ khí lợi hại mà OOP mang lại. Nếu tìm hiểu sâu hơn nữa, chúng ta sẽ thấy tính trừu tượng được áp dụng rất nhiều trong Design Pattern và thường xuyên được các cao thủ mang ra để lòe thiên hạ.
Bài viết vẫn còn khá nhiều thiếu sót trong cách trình bày và chỉ là cách hiểu của mình về OOP, các bạn có ý kiến đóng góp thì đừng ngại để lại comment dưới phần bình luận nhé.

Đón xem phần 2: Encapsulation tuyệt kỹ ẩn thân vào 08/10/2018 nhé.

--

--