2016-06-01 18 views
9

Tôi hiểu tính đa hình và mơ hồ hiểu quá tải, nhưng sẽ đánh giá cao một người hiểu thấu đáo hai khái niệm để giải thích sự khác biệt phân loại là gì và liệu quá tải hay không phải là dạng đa hình (dường như không đồng ý về điều này).Sự khác biệt giữa đa hình và quá tải là gì?

+1

Bạn có thể làm tồi tệ hơn việc tra cứu trên Wikipedia: https://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29 – Galik

+0

Haskell có * đa hình tham số *, nơi bạn có các hàm hoạt động giống hệt nhau trên nhiều loại, ví dụ: 'length :: [a] -> Int' làm việc cho danh sách các chuỗi, danh sách của đôi, vv Tất cả bạn cần là một định nghĩa duy nhất, như một giá trị đa hình tham số không quan tâm về tham số là gì, chỉ nơi nó được sử dụng . Nó cũng có typeclasses mà nó sử dụng cho * ad hoc polymorphism *, các chức năng mà việc triển khai phụ thuộc vào loại, ví dụ: 'show :: Show a => a -> String' là một họ các hàm với định nghĩa riêng của nó:' show :: Int -> String, show :: Double -> String, ... '. – rampion

Trả lời

8

Đa hình, cốt lõi là nhiều thứ có hành vi nhất quán nhất quán, để bạn có thể thay thế trong một thuật toán hoặc quy trình cụ thể. Vì vậy, miễn là tất cả đều cung cấp giao diện dự kiến, quá trình này vẫn hoạt động.

Quá tải không thực sự có nền tảng như vậy.Nó chỉ đơn thuần là khả năng đặt tên cho hai hoặc nhiều hàm có cùng tên, miễn là chúng có các danh sách tham số khác nhau. Trình biên dịch tìm ra chức năng nào bạn thực sự có ý nghĩa dựa trên các loại đối số bạn vượt qua.

Quá tải có thể được sử dụng để tạo đa hình. Hãy xem xét những điều sau:

template<typename T> 
void func(T t) {call(t);} 

Điều này sẽ gọi call, chuyển t làm tham số. Điều này sẽ hoạt động miễn là bạn cung cấp loại Tcall(t) là mã C++ hợp pháp. Bạn có thể làm điều này bằng cách làm quá tải chức năng call cho bất cứ điều gì loại bạn quan tâm trong việc sử dụng với func:

void call(int); 
void call(float); 
void call(vector<int>); 

Bằng cách này, func là một chức năng mà là đa hình (tĩnh) liên quan đến tham số của nó. Nó có thể thực hiện hoạt động của nó trên bất kỳ loại nào, miễn là loại đó có giao diện thích hợp. Giao diện đó là khả năng gọi hàm call với một biến kiểu đó.

func(5); //Legal 
func(13.4); //Legal 
func(vector<int>{4, 3, 2, 1}); //Legal 
func(vector<float>{}); //NOT legal 

Ở đây, chúng tôi sử dụng chức năng quá tải của call để tạo ra một hình thức polymophism qua func chức năng. Nhưng điều này không có nghĩa là quá tải đa hình.

Quá tải là công cụ ngôn ngữ. Đa hình là một khái niệm. Đa hình là làm cho nhiều đối tượng hoạt động theo cùng một cách. Quá tải chỉ là một cách để cung cấp cho các chức năng khác nhau cùng tên.

4

Đa hình: một phương pháp có nhiều triển khai tùy thuộc vào loại (các) đối số mà nó được viện dẫn. Thường không được biết tại thời gian biên dịch. Số đối số được cố định và trong C++ đối số duy nhất có loại quan trọng là số đầu tiên (this). Trong C++, phiên bản phổ biến này đòi hỏi một lớp cơ sở với các phương thức virtual.

Quá tải: một tên thực sự là nhiều phương pháp tùy thuộc vào số lượng và loại đối số mà nó được gọi. Luôn quyết định thời gian biên dịch. Không có lớp cơ sở nào có liên quan.

Nếu bạn muốn một sự tương tự: đa hình là khi bạn thuê một tá chuyên gia cơ khí để làm việc trên xe hơi, và mỗi người trong số họ có chức năng như do_work(vehicle)take_vacation(duration). Mỗi cái có một cái gì đó khác nhau nhưng tất cả chúng đều có chữ ký giống với đối số "ẩn" này trong C++ (aka self trong Python, v.v.). Quá tải là khi bạn thuê cơ chế tổng quát và mỗi người trong số họ có do_work(steering), do_work(lighting), do_work(engine), v.v.

+0

Đoạn cuối cùng là vàng !! –

+0

Còn về "đa hình thời gian biên dịch" thì sao? –

+0

@NickyC: Có hai loại đa hình thời gian biên dịch trong C++: loại đó là một tối ưu hóa vì trình biên dịch thấy cần triển khai thực hiện nào và loại đó là một tính năng ngôn ngữ sử dụng lập trình meta mẫu. Đầu tiên vẫn dựa vào các phương thức 'virtual' nhưng cải thiện hiệu suất; thứ hai dựa vào lập trình sử dụng các loại một cách rõ ràng. –

1

Quá tải là tập hợp con của Đa hình. Đa hình có hai loại: Trên thời gian chạy và biên dịch. Quá tải thuộc về một trong những thứ hai (có một số khía cạnh khác của thời gian biên dịch/đa hình tĩnh cũng như mẫu, chức năng con trỏ)

Thông thường các tác giả tham khảo Polymorphism đến một thực hiện on the Run-time (trừ khi xác định) và nếu bạn đang nói về Đa hình đó, sau đó rõ ràng rằng một được thực hiện trên runtime (John câu trả lời đã thu hút sự khác biệt cơ bản wrt thừa kế/chức năng ảo trong câu trả lời của mình ở đó) và quá tải là được thực hiện trên c ompile thời gian khi các thông số chức năng của bạn xác định quá tải được gọi.

quá tải - Static Polymorphism(Minh họa)

Tiếp theo ảnh chụp màn hình có thể chứng minh như thế nào chức năng quá tải là tĩnh (giải quyết trước khi thời gian chạy)

enter image description here

PS

Trong trường hợp, bạn muốn xem, đây là câu hỏi có liên quan về overloading and virtual functions

+2

C++ cũng có "đa hình tĩnh" mà không phải là quá tải. –

+0

@JohnZwinck Tôi có nghĩa là một loại đa hình tĩnh của nó. Nhưng cảm ơn vì đã thu hút sự chú ý ở đó. Tôi đã cập nhật nó –

+0

Tôi không nghĩ rằng tất cả quá tải hàm là một loại đa hình động. Trình biên dịch phải giải quyết quá tải hàm phi ảo tại thời gian biên dịch. –

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