- vừa được xem lúc

004: Các tính chất cơ bản trong OOP P2

0 0 37

Người đăng: Dat Bui

Theo Viblo Asia

Bài viết nằm trong series Object-Oriented Design from real life to software.

Với phần trước, chúng ta đã tìm hiểu về AbstractionEncapsulation. Bài viết hôm nay sẽ giới thiệu 2 tính chất còn lại của OOP là:

  • Inheritance.
  • Polymorphism.

1) Inheritance

Kế thừa là thừa hưởng, gìn giữ và tiếp tục phát huy các giá trị tinh thần hoặc những di sản văn hóa của dân tộc - Theo từ điển tiếng Việt.

Nói một cách dễ hiểu, mình được thừa kế mảnh đất do tổ tiên để lại, mình có thể làm bất kì điều gì, trồng cây, xây nhà, thả cá... trên mảnh đất này. Chả tội gì đi làm quần quật ngày đêm làm gì cho khổ. Bốc phét thế chứ chưa có gì trong tay nên mình mới ngồi đây viết nhảm thế này ?.

Áp dụng vào lập trình, khi tạo một class mới, không nhất thiết phải build từ đầu. Trước hết cần đi tìm xem tổ tiên có để lại gì cho hậu thế không? Nếu chương trình đã tồn tại class giống y hệt, hoặc giống một phần thứ chúng ta cần, inheritance sẽ phát huy tác dụng trong trường hợp này.

Vài tính chất của inheritance:

  • Tạo một class mới dựa trên class có sẵn.
  • Class mới kế thừa các attributes và methods của class có sẵn.
  • Từ đó đem lại lợi ích to lớn là sử dụng lại code nhiều nhất có thể.

Ví dụ, mình muốn mở một tiệm bánh nhỏ và cần hệ thống quản lý. Sơ sơ đã mường tượng ra một vài object như Customer, Employee, Mooncake, Cupcake...

Mô hình hóa cho dễ hình dung. Nhìn thoáng qua thấy rằng CustomerEmployee có một vài điểm chung.

Áp dụng inheritance, thay vì mỗi class đều có những attributesmethods giống nhau, ta sẽ tạo base class mới chứa các điểm chung. CustomerEmployee sẽ kế thừa các điểm chung đó từ base class.

Như vậy, Customer sẽ kế thừa toàn bộ thông tin của Person, bao gồm attributesmethods mà không cần viết lại code. Sau đó sẽ thêm các attributesmethods của riêng Customer.

Person được gọi là super class/parent class hoặc base class. Customer/Employeesub class/child class hoặc derived class.

Nếu kinh doanh tốt và muốn mở rộng thị trường, mình cần thuê thêm shipper. Lúc này chỉ cần tạo class mới là Shipper kế thừa từ Person, thêm một vài thông tin dành riêng cho shipper là ok.

Ngoài ra, mình muốn quản lý thêm thông tin email của tất cả mọi người. Lúc này sẽ thêm email vào Person, sửa một chỗ nhưng apply được cho toàn bộ.

Trên thực tế, nhiều người có thể cùng thừa kế một mảnh đất, hoặc một người thừa kế được nhiều mảnh đất.

Trong lập trình, một vài ngôn ngữ như Python, C++ cho phép đa kế thừa nhiều mảnh đất ?. Một sub class có thể kế thừa nhiều super class. Lúc này toàn bộ các attributesmethod của tất cả super class đều thuộc về sub class.

Hôm nọ Euro hơi yêu UK một tí nên phải bán một mảnh đi lấy vốn làm ăn. Có 3 mảnh nhưng không biết bán mảnh nào. Sau một hồi phân vân thì.. chọn bừa một mảnh.

Câu chuyện không đơn giản như trên thực tế, với lập trình đó là cả một sự.. rối rắm. Class A và class B đều có chung method inherit(). Nếu class C kế thừa cả 2 class AB, khi thực thi inherit() sẽ không biết nên thực thi method của class nào.

Do vậy các ngôn ngữ như Java, C#, Swift... sử dụng đơn kế thừa với class cho dễ quản lý.

Nhưng không thể phủ nhận lợi thế của multi-inheritance. Java không hoàn toàn bỏ đa kế thừa mà sẽ sử dụng với interface thay vì class.

2) Polymorphism

Tính chất cuối cùng là polymorphism - đa hình. Giống như Tôn Ngộ Không có 72 phép biến hóa, thích biến thành gì thì biến, không biến.. thái là được ?. Đùa chứ không liên quan gì đâu.

Đa hình cũng có đa hình this đa hình that là:

  • Dynamic/Run-time polymorphism.
  • Static/Compile-time polymorphism.

2.1) Dynamic polymorphism

Mình thích ăn khoai tây chiên nhưng lại sợ dầu mỡ, thôi nướng cho healthy ?. Mình có 2 loại là nồi nướng truyền thốnglò chiên không dầu. Cả 2 đều dùng chiên khoai tây được mà không cần dầu. Cùng input/output nhưng cơ chế hoạt động có sự khác biệt.

Quay lại ngôn ngữ lập trình, có một vài cách implement dynamic polymorphism sử dụng tính chất inheritance như sau:

Mình sẽ tạo BasicOven trước, sau đó là AirFryer kế thừa từ BasicOven, định nghĩa lại method bake() để thay thế default implementation của BasicOven. Kĩ thuật này được gọi là overriding. Như vậy cả 2 đều có cùng method bake() nhưng cách thực thi là độc lập, riêng biệt.

Ngoài ra còn một cách khác, áp dụng thêm abstraction, cả BasicOvenAirFryer sẽ kế thừa chung một abstract class hoặc interface.

Interface, abstract class, thậm chí class khi implement với inheritance đều có thể tạo ra dynamic polymorphism.

Vậy lợi ích của dynamic polymorphism là gì?

Nó cho phép chúng ta có thể sử dụng bất kì loại lò nướng nào miễn là nó có khả năng tạo ra đĩa khoai tây chiên thơm ngon giòn rụm. Thậm chí có thể dùng lò nướng than tổ ong cũng có thể cho ra output tương tự.

Khi kết hợp với inheritance, ta có thể tạo nên những đoạn code có khả năng thay đổi behavior trong quá trình runtime. Giống việc mình đang vận hành khu nấu bếp, khi thực khách yêu cầu món khoai tây chiên, mình có thể sử dụng bất kì loại lò nướng nào miễn làm ra món đúng yêu cầu là được. Do vậy nó được gọi là dynamic polymorphism hay run-time polymorphism.

2.2) Static polymorphism

Một hình thức polymorphism khác là static polymorphism hoặc compile-time polymorphism. Được implement với code dưới tên gọi là method overloading để phân biệt với method overriding.

Nếu mình nướng khoai, chắc chắn kết quả sẽ là đĩa khoai nướng. Nếu mình nướng rib-eye steak, kết quả là đĩa steak thơm ngon khó lòng cưỡng lại. Cùng một hành động nướng nhưng với mỗi input khác nhau sẽ cho output khác nhau. Và ta có thể xác định được chính xác output là gì mà chưa cần thực thi, do vậy nó được gọi là static polymorphism.

Nhờ method overloading, sẽ có nhiều version của một method với các parameters khác nhau, có thể cho ra cùng hoặc khác output. Trong lập trình, nó nói đến việc một class có nhiều method cùng tên nhưng khác arguments hoặc khác dữ liệu trả về.

Trong thực tế khi implement, các overload method thường có chung functionality, chung kiểu dữ liệu trả về, chỉ khác arguments.

Một vài ngôn ngữ không support method overloading, một vài ngôn ngữ có support trong đó bao gồm Java.

Với static polymorphism, khá dễ dàng để biết được method nào đang được gọi. Tuy nhiên với dynamic polymorphism nó là cả một sự nỗ lực.. để biết method của class nào sẽ được thực thi.

Với 4 tính chất này của OOP, nó giúp ta tối ưu việc quản lý source code, dễ dàng phát triển và đặc biệt là mở rộng ứng dụng sau này.

Reference

Reference in series https://viblo.asia/s/object-oriented-design-from-real-life-to-software-z45bx89oZxY

© Dat Bui

Bình luận

Bài viết tương tự

- vừa được xem lúc

Chương 5 Object oriented programming

Chương 5 Object oriented programming. Tôi lần đầu tiên được giới thiệu về lập trình hướng đối tượng ở trường cao đẳng nơi tôi đã có một giới thiệu tóm tắc về c++.

0 0 24

- vừa được xem lúc

SOLID trong OOP và ví dụ dễ hiểu bằng Python

Thế SOLID là gì? SOLID là cứng . Đùa tí Đây là các nguyên lý thiết kế trong OOP, được ghép lại từ các chữ cái đầu của Single Responsibility, Open Close Principle, Liskov Substitution Principle, Interf

0 0 27

- vừa được xem lúc

002: Object và Class trong OOP

Bài viết nằm trong series Object-Oriented Design from real life to software. Về mặt ý tưởng, OOP nói đến việc áp dụng từ thế giới thực vào thế giới lập trình.

0 0 30

- vừa được xem lúc

001: Procedural programming và Object-Oriented programming

Bài viết nằm trong series Object-Oriented Design from real life to software. 1) Procedural programming.

0 0 31

- vừa được xem lúc

003: Các tính chất cơ bản trong OOP P1

Bài viết nằm trong series Object-Oriented Design from real life to software. . . Abstraction.

0 0 41

- vừa được xem lúc

OOP Implementation

Disadvantages of previous paradigms. Các phương pháp lập trình trước kia (procedural programming & structured programming) đòi hỏi một sự quản lý cực kỳ chặt chẽ khi code.

0 0 32