2014-05-11 18 views
9

Tôi không thể tìm thấy sự khác biệt chính. Và tôi rất bối rối khi chúng ta có thể sử dụng di sản thừa kế và khi chúng ta có thể sử dụng subtyping. Tôi đã tìm thấy một số định nghĩa nhưng chúng không rõ ràng lắm.Sự khác biệt giữa phân nhóm và kế thừa trong lập trình OO là gì?

Sự khác nhau giữa phân loại và kế thừa trong lập trình hướng đối tượng là gì?

+3

Bạn thấy chúng được mô tả là khác ở đâu? –

Trả lời

5

Nếu bạn kế thừa riêng tư trong C++, bạn sẽ nhận được thừa kế mà không cần gõ phụ. Đó là, đưa ra:

class Derived : Base  // note the missing public before Base 

Bạn không thể viết:

Base * p = new Derived(); // type error 

Derived không phải là một subtype của Base. Bạn chỉ thừa hưởng việc triển khai, không phải kiểu.

+2

Về mặt kỹ thuật, bạn vẫn nhận được kiểu con với quyền thừa kế riêng, chỉ là kiểu phụ là riêng tư đối với lớp ... – Mankarse

+0

Nếu tôi thay đổi thừa kế thành: lớp Xuất phát: cơ sở công cộng Tôi có thể viết: Base * p = new Nguồn gốc(); –

6

Thừa kế là về việc đạt được các thuộc tính (và/hoặc chức năng) của các loại siêu. Ví dụ:

class Base { 
    //interface with included definitions 

} 

class Derived inherits Base { 
    //Add some additional functionality. 
    //Reuse Base without having to explicitly forward 
    //the functions in Base 
} 

Ở đây, một Derived không thể được sử dụng khi một Base dự kiến, nhưng có thể đóng vai trò tương tự như một Base, trong khi thêm hành vi hoặc thay đổi một số khía cạnh của hành vi Base s. Thông thường, Base sẽ là một lớp trợ giúp nhỏ cung cấp cả giao diện và triển khai cho một số chức năng phổ biến mong muốn.

loại con-đa hình là về việc thực hiện một giao diện, và do đó có khả năng thay thế hiện thực khác nhau của giao diện mà tại thời gian chạy:

class Interface { 
    //some abstract interface, no definitions included 
} 

class Implementation implements Interface { 
    //provide all the operations 
    //required by the interface 
} 

Ở đây, một Implementation thể được sử dụng bất cứ nơi nào một Interface là cần thiết, và triển khai khác nhau có thể được thay thế trong thời gian chạy. Mục đích là để cho phép mã sử dụng Interface để trở nên hữu ích hơn.

Sự nhầm lẫn của bạn là hợp lý. Java, C#, và C++ tất cả liên kết hai ý tưởng này thành một hệ thống phân cấp lớp đơn. Tuy nhiên, hai khái niệm không giống nhau, và có tồn tại các ngôn ngữ tách biệt hai khái niệm.

+0

Bạn có thể liệt kê các ngôn ngữ tách riêng hai ngôn ngữ này không? – letronje

+0

@letronje: Thừa kế không có phân loại phụ thường được thực hiện thông qua một khái niệm [mixin] (https://en.wikipedia.org/wiki/Mixin) (nhưng mixin thường ít bị hạn chế hơn so với thừa kế). Ví dụ, trong D, bạn có thể viết [template mixins] (http://dlang.org/template-mixin.html), về cơ bản là một cách để chèn mã và dữ liệu vào một phạm vi tùy ý. – Mankarse

8

Một người họ hàng không may đã chết và để lại hiệu sách cho bạn.

Bây giờ bạn có thể đọc tất cả sách ở đó, bán chúng, bạn có thể xem tài khoản, danh sách khách hàng, v.v. Thừa kế là một dạng tái sử dụng mã.

Bạn cũng có thể tự mở lại cửa hàng sách, đảm nhận vai trò và trách nhiệm của người thân, mặc dù bạn thêm một số thay đổi của riêng mình - đây là subtyping - bây giờ bạn là chủ sở hữu hiệu sách người thân của bạn từng là. Sub2ping là một thành phần quan trọng của OOP - bạn có một đối tượng của một kiểu nhưng đáp ứng giao diện của một kiểu khác, vì vậy nó có thể được sử dụng ở bất cứ nơi nào mà đối tượng khác có thể đã được sử dụng.

Trong các ngôn ngữ bạn đã liệt kê trong câu hỏi - C++, Java và C# - cả hai là (gần như) luôn được sử dụng cùng nhau, và do đó cách duy nhất để kế thừa từ thứ gì đó là phân loại nó và ngược lại. Nhưng các ngôn ngữ khác không nhất thiết phải hợp nhất hai khái niệm.

16

Ngoài các câu trả lời đã đưa ra, đây là link cho một bài viết mà tôi nghĩ là có liên quan. Đoạn trích:

Trong khuôn khổ hướng đối tượng, kế thừa thường được trình bày như một tính năng đi đôi với phân nhóm khi tổ chức các kiểu dữ liệu trừu tượng trong phân cấp lớp. Tuy nhiên, hai là ý tưởng trực giao.

  • Loại phụ đề cập đến khả năng tương thích của giao diện. Kiểu B là một kiểu con của A nếu mọi hàm có thể được gọi trên một đối tượng kiểu A cũng có thể được gọi trên một đối tượng kiểu B.
  • Thừa kế đề cập đến việc sử dụng lại các triển khai. Một loại B được thừa kế từ một loại khác A nếu một số chức năng cho B được viết theo các chức năng của A.

Tuy nhiên, phân loại và thừa kế không cần phải đi đôi với nhau. Hãy xem xét cấu trúc dữ liệu deque, một hàng đợi hai kết thúc. Chèn và xóa hỗ trợ deque ở cả hai đầu, do đó, nó có bốn hàm insert-front, delete-front, insert-reardelete-rear. Nếu chúng tôi chỉ sử dụng insert-reardelete-front, chúng tôi sẽ nhận được hàng đợi bình thường. Mặt khác, nếu chúng tôi chỉ sử dụng insert-frontdelete-front, chúng tôi sẽ có một ngăn xếp. Nói cách khác, chúng ta có thể thực hiện các hàng đợi và ngăn xếp về mặt deques, do đó, kiểu dữ liệu, StackQueue kế thừa từ Deque. Mặt khác, không phải Stack không Queue là các loại phụ của Deque vì chúng không hỗ trợ tất cả các chức năng được cung cấp bởi Deque. Trong thực tế, trong trường hợp này, Deque là một loại phụ của cả hai StackQueue!

Tôi nghĩ rằng Java, C++, C# và ilk của họ đã góp phần vào sự nhầm lẫn, như đã lưu ý, bởi thực tế là chúng hợp nhất cả hai ý tưởng vào một hệ thống phân cấp lớp đơn. Tuy nhiên, tôi nghĩ rằng ví dụ được đưa ra ở trên không công bằng cho các ý tưởng theo một cách khá thuyết phục về ngôn ngữ. Tôi chắc rằng những người khác có thể đưa ra nhiều ví dụ hơn.

+2

Đó là một đoạn trích được chọn hoàn hảo. Cảm ơn bạn đã chia sẻ đã giúp xóa bỏ những nghi ngờ của tôi. – CapturedTree

Các vấn đề liên quan