2009-07-25 6 views
15

Làm thế nào để khái niệm (tức là những người gần đây đã giảm từ tiêu chuẩn C++ 0x) khác với giao diện trong các ngôn ngữ như Java?Các khái niệm khác với Giao diện như thế nào?

+2

C++ không có bất kỳ thứ gì được gọi là Giao diện, trong khi ... oh ... hãy đợi, chúng giống nhau. Nhưng bạn sẽ phải nói những gì bạn có nghĩa là bởi "Giao diện" trước khi câu hỏi có thể được trả lời. Giao diện Java? Khái niệm OOP chung của một giao diện? Khái niệm chung về giao diện là "I" trong API? –

+1

Các lớp học ảo không phải là giao diện thuần túy chỉ với một tên khác? – AraK

+0

Có, không làm rõ điều đó. Đã chỉnh sửa. – user4812

Trả lời

21

Các khái niệm dành cho tính đa hình thời gian biên dịch, Điều đó có nghĩa là mã chung tham số. Giao diện dành cho đa hình thời gian chạy.

Bạn phải triển khai giao diện khi bạn triển khai Khái niệm. Sự khác biệt là bạn không cần phải nói rõ ràng rằng bạn đang thực hiện một Khái niệm. Nếu giao diện được yêu cầu được khớp thì không có vấn đề gì. Trong trường hợp giao diện, ngay cả khi bạn đã triển khai tất cả các chức năng bắt buộc, bạn phải kích thích nói rằng bạn đang triển khai nó!


Tôi sẽ cố gắng để làm rõ câu trả lời của tôi :)

Hãy tưởng tượng rằng bạn đang thiết kế một container chấp nhận bất kỳ loại có kích thước chức năng thành viên. Chúng tôi chính thức hóa khái niệm và gọi nó là HasSize, tất nhiên chúng ta nên định nghĩa nó ở nơi khác nhưng đây không phải là một ví dụ nữa.

template <class HasSize> 
class Container 
{ 
    HasSize[10]; // just an example don't take it seriously :) 
// elements MUST have size member function! 
}; 

Sau đó, Hãy tưởng tượng chúng ta đang tạo một thể hiện của chúng tôi container và chúng tôi gọi nó là myShapes, Shape là một lớp cơ sở và nó xác định kích thước chức năng thành viên. Square và Circle chỉ là con của nó. Nếu Shape không xác định kích thước thì một lỗi sẽ được tạo ra.

Container<Shape> myShapes; 

if(/* some condition*/) 
    myShapes.add(Square()); 
else 
    myShapes.add(Circle()); 

tôi hy vọng bạn thấy Shape có thể được kiểm tra đối HasSize tại thời gian biên dịch, không có lý do để làm việc kiểm tra tại thời gian chạy. Không giống như các yếu tố của myShapes, chúng ta có thể định nghĩa một hàm đó thao túng họ:

void doSomething(Shape* shape) 
{ 
    if(/* shape is a Circle*/) 
     // cast then do something with the circle. 
    else if(/* shape is a Square */) 
     // cast then do something with the square. 
} 

Trong chức năng này, bạn không thể biết điều gì sẽ được thông qua cho đến thời gian chạy một vòng hoặc một quảng trường!

Chúng là hai công cụ cho một công việc tương tự, mặc dù Giao diện hoặc bất kỳ thứ gì bạn gọi - có thể thực hiện gần như cùng một công việc của các khái niệm trong thời gian chạy nhưng bạn mất tất cả lợi ích của việc kiểm tra và tối ưu hóa thời gian biên dịch!

+0

Người giải quyết có thể giải thích những gì sai với câu trả lời của tôi không? – AraK

+0

Ya, câu trả lời này có vẻ ổn với tôi. +1 – GManNickG

+0

Tôi là kẻ phá hủy. AraK đã hoàn toàn chỉnh sửa lại câu trả lời của anh ấy, nhưng việc chỉnh sửa lại không hiển thị vì những thay đổi của SO. –

6

Các khái niệm là các loại (lớp) thích cho mẫu: nó chỉ dành cho phía lập trình chung của ngôn ngữ. Bằng cách đó, nó không có nghĩa là thay thế các lớp giao diện (giả sử bạn có nghĩa là các lớp trừu tượng hoặc tương đương C++ hoặc C++ khác) vì nó chỉ có nghĩa là kiểm tra các kiểu được sử dụng trong các tham số mẫu để phù hợp với các yêu cầu cụ thể. Việc kiểm tra kiểu chỉ được thực hiện tại thời gian biên dịch giống như tất cả việc tạo mã mẫu và trong khi các lớp giao diện có tác động đến việc thực thi thời gian chạy.

1

Đó là sự khác biệt ít nhiều trong quan điểm. Trong khi một giao diện (như trong C#) được xác định tương tự như một lớp cơ sở, một khái niệm cũng có thể được kết hợp tự động (tương tự như gõ vịt trong Python). Vẫn chưa rõ mức C++ nào sẽ hỗ trợ kết hợp khái niệm tự động, đó là một trong những lý do tại sao họ bỏ nó.

0

Các khái niệm là giao diện ngầm.Trong C# hoặc Java, một lớp phải thực hiện rõ ràng một giao diện, trong khi trong C++ một lớp là một phần của một khái niệm chỉ miễn là nó đáp ứng các ràng buộc của khái niệm.

Lý do bạn sẽ thấy các khái niệm trong C++ chứ không phải trong Java hoặc C# là vì C++ không thực sự có "giao diện". Thay vào đó, bạn có thể mô phỏng một giao diện bằng cách sử dụng nhiều lớp cơ sở thừa kế và trừu tượng, không có thành phần. Đây là một phần của một hack và có thể là một nhức đầu để làm việc với (ví dụ như thừa kế ảo và The Diamond Problem). Giao diện đóng một vai trò quan trọng trong OOP và đa hình, và vai trò đó chưa được đáp ứng đầy đủ trong C++ cho đến nay. Các khái niệm là câu trả lời cho vấn đề này.