Trong lập trình, mã tái sử dụng là việc sử dụng phần mềm hiện có để xây dựng phần mềm mới bằng cách sử dụng các nguyên tắc tái sử dụng. Tái sử dụng mã được coi là một chức năng sản xuất cơ bản trong các doanh nghiệp thâm dụng công nghệ thông tin. Nó được thúc đẩy trong các hệ thống hướng đối tượng bằng cách thiết lập mối quan hệ giữa các lớp. Có hai cách cơ bản để thiết lập các mối quan hệ này trong lập trình hướng đối tượng - Kế thừa và Thành phần. Thực hiện kế thừa là một cách để liên kết các lớp nhưng OOP cung cấp một loại mối quan hệ mới giữa các lớp được gọi là thành phần. Bằng cách thiết lập mối quan hệ giữa các lớp mới và các lớp hiện có, một lớp mới có thể kế thừa hoặc nhúng mã từ một hoặc nhiều lớp hiện có.
Trong OOP, kế thừa là phương pháp mà theo đó một đối tượng có được các đặc điểm của một hoặc nhiều đối tượng khác. Đây là một trong những công cụ mạnh nhất để triển khai khả năng sử dụng lại mã trong OOP. Khi sử dụng tính kế thừa, một lớp mới có thể được tạo bằng cách thiết lập mối quan hệ cha-con với các lớp hiện có. Thành phần đối tượng là một thay thế cho kế thừa lớp. Sử dụng một đối tượng trong một đối tượng khác được gọi là thành phần. Trong nhiều trường hợp, bạn muốn sử dụng một đối tượng làm trường trong một lớp khác vì dễ dàng tạo các lớp phức tạp bằng cách sử dụng các lớp được thiết kế tốt, được viết trước đó làm thành phần. Đây được gọi là thành phần. Vâng, cả kế thừa và thành phần đều cung cấp chức năng tương đương trong nhiều trường hợp, thành phần đối tượng là mô hình tái sử dụng tốt hơn so với kế thừa lớp. Bài viết này so sánh hai cách tiếp cận.
Kế thừa là một trong những công cụ mạnh nhất để thực hiện khả năng sử dụng lại mã trong lập trình hướng đối tượng. Nó đề cập đến chức năng mà một đối tượng có được các đặc điểm của một hoặc nhiều đối tượng khác. Kế thừa trong C ++ có nghĩa là bạn có thể tạo các lớp lấy các thuộc tính của chúng từ các lớp hiện có. Điều này có nghĩa là bạn chuyên môn hóa một lớp để tạo mối quan hệ giữa các lớp dẫn đến sự kết hợp mạnh mẽ giữa lớp cơ sở và lớp dẫn xuất. Việc thực hiện kế thừa thúc đẩy khả năng sử dụng lại mã bởi vì các lớp mới được tạo từ các lớp hiện có. Kế thừa lớp cũng giúp dễ dàng sửa đổi việc thực hiện đang được sử dụng lại. Nhưng kế thừa lớp cũng có một số nhược điểm. Đầu tiên, vì tính kế thừa được xác định tại thời gian biên dịch, bạn không thể thay đổi các triển khai được kế thừa từ các lớp cha trong thời gian chạy.
OOP cung cấp một mối quan hệ khác giữa các lớp được gọi là thành phần, còn được gọi là mối quan hệ có-có. Nếu các tính năng của một đối tượng cần phải là một phần của đối tượng khác, mối quan hệ gọi cho thành phần. Để soạn một lớp từ các lớp hiện có, một đối tượng của mỗi lớp nên được khai báo là thành viên của lớp mới. Nói một cách đơn giản, sử dụng một đối tượng trong một đối tượng khác được gọi là thành phần. Nhiều lần, bạn có thể muốn sử dụng một đối tượng làm trường trong một lớp khác. Bạn sử dụng một đối tượng bên trong một lớp trong thành phần. Không giống như kế thừa lớp, thành phần đối tượng được xác định động trong thời gian chạy thông qua các đối tượng có được các tham chiếu đến các đối tượng khác. Ngoài ra, thành phần cung cấp một cách tốt hơn để sử dụng một đối tượng mà không ảnh hưởng đến các chi tiết bên trong của đối tượng, đó là nơi bố cục hữu ích.
Mặc dù cả kế thừa và thành phần đều thúc đẩy khả năng sử dụng lại mã trong hệ thống hướng đối tượng bằng cách thiết lập mối quan hệ giữa các lớp và chúng cung cấp chức năng tương đương theo nhiều cách, chúng sử dụng các cách tiếp cận khác nhau. Với tính kế thừa, bạn có thể tạo các lớp lấy các thuộc tính của chúng từ các lớp hiện có để trong khi sử dụng tính kế thừa để tạo một lớp, bạn có thể mở rộng trên một lớp hiện có. Ngược lại, sử dụng một đối tượng trong một đối tượng khác được gọi là thành phần. Thành phần đối tượng là một thay thế cho kế thừa lớp. Nếu các tính năng của một đối tượng cần phải là một phần của đối tượng khác, mối quan hệ gọi cho thành phần.
Để kế thừa, bạn chuyên môn hóa một lớp để tạo mối quan hệ giữa is-is giữa các lớp dẫn đến sự kết hợp chặt chẽ giữa lớp cơ sở và lớp dẫn xuất. Nó cho phép phân cấp các lớp được thiết kế và hệ thống phân cấp bắt đầu với lớp chung nhất và chuyển sang các lớp cụ thể hơn. Bằng cách thực hiện kế thừa, các hàm thành viên từ một lớp trở thành thuộc tính của lớp khác mà không mã hóa chúng rõ ràng trong lớp. Trong thành phần, bạn sử dụng một đối tượng bên trong một lớp và bất kỳ yêu cầu nào đến đối tượng đều được chuyển tiếp đến đối tượng. Các chi tiết bên trong không được tiếp xúc với nhau trong bố cục, do đó, đây là mối quan hệ có một.
Kế thừa lớp được định nghĩa tại thời gian biên dịch, do đó bạn không thể thay đổi các triển khai được kế thừa từ các lớp cha trong thời gian chạy. Bởi vì sự kế thừa làm lộ ra một lớp con với các chi tiết về việc thực hiện của cha mẹ nó, nó thường phá vỡ sự đóng gói. Mọi thay đổi trong lớp cha sẽ phản ánh trong lớp con có thể tạo ra vấn đề khi bạn cố gắng sử dụng lại lớp con. Thành phần đối tượng, ngược lại, được định nghĩa động tại thời gian chạy thông qua các đối tượng có được các tham chiếu đến các đối tượng khác. Và bởi vì các đối tượng chỉ được truy cập thông qua giao diện của chúng, nó sẽ không phá vỡ đóng gói. Bất kỳ đối tượng nào cũng có thể được thay thế vào thời gian chạy bởi một đối tượng khác miễn là nó có cùng loại.
Trong nhiều trường hợp, bạn muốn sử dụng một đối tượng làm trường trong một lớp khác vì các lớp phức tạp dễ tạo hơn bằng cách sử dụng các lớp được thiết kế tốt, được viết trước đó. Đây là nơi bạn sử dụng thành phần. Kế thừa cung cấp một cách để sử dụng lại mã bằng cách mở rộng một lớp với nỗ lực tối thiểu, đây là lý do tại sao thừa kế là một công cụ có giá trị trong việc thiết lập mối quan hệ giữa các lớp. Nói chung, tốt hơn là sử dụng bố cục vì nó cung cấp một cách để sử dụng một đối tượng mà không ảnh hưởng đến các chi tiết bên trong của đối tượng là nơi mà bố cục có ích. Kế thừa không phải là không có vấn đề, nhưng giống như thừa kế, thành phần đối tượng làm tăng mối quan tâm về hiệu suất tương tự đối với việc tạo và hủy đối tượng.