2008-10-27 33 views
59

Tôi hiểu rằng họ buộc bạn phải thực hiện các phương pháp và những điều tôi không thể hiểu là tại sao bạn muốn sử dụng chúng. Ai có thể cho tôi một ví dụ hay giải thích tốt về lý do tại sao tôi muốn thực hiện điều này.Tại sao tôi muốn sử dụng Giao diện?

+2

Mọi người, anh ấy không yêu cầu định nghĩa. –

+2

Tôi đã vật lộn trong một thời gian dài với toàn bộ giao diện và điều kế thừa. Sự khác biệt giữa kế thừa một lớp trừu tượng và thực hiện một giao diện là gì? Không có giáo viên nào từng trải qua cho đến khi tôi đọc Head First - Design Patterns. Nó nhẹ và không đắt. –

+3

Về mặt kỹ thuật, một giao diện là một lớp chỉ với các phương thức trừu tượng. Vì vậy, Java thực sự có nhiều thừa kế, (chỉ được phép cho các giao diện.) Lý do cho điều này là vấn đề với đa kế thừa chủ yếu liên quan đến các biến mẫu. (và một phần phương pháp triển khai) – Hugo

Trả lời

1

Có một số lý do để làm như vậy. Khi bạn sử dụng một giao diện, bạn đã sẵn sàng trong tương lai khi bạn cần phải tái cấu trúc/viết lại mã. Bạn cũng có thể cung cấp một loại API chuẩn hóa cho các hoạt động đơn giản.

Ví dụ, nếu bạn muốn viết một thuật toán sắp xếp như quicksort, tất cả những gì bạn cần để sắp xếp danh sách các đối tượng là bạn có thể so sánh hai đối tượng thành công. Nếu bạn tạo ra một giao diện, nói rằng ISortable, hơn bất cứ ai tạo ra các đối tượng có thể thực hiện giao diện ISortable và họ có thể sử dụng mã sắp xếp của bạn.

Nếu bạn đang viết mã sử dụng bộ nhớ cơ sở dữ liệu và bạn viết vào giao diện lưu trữ, bạn có thể thay thế mã đó xuống dòng.

Giao diện khuyến khích khớp nối lỏng lẻo hơn với mã của bạn để bạn có thể linh hoạt hơn.

3

Giao diện hoàn toàn cần thiết trong một hệ thống hướng đối tượng dự kiến ​​sẽ tận dụng tốt tính đa hình.

Ví dụ điển hình có thể là IVehicle, có phương thức Move(). Bạn có thể có các lớp Car, Bike và Tank, thực hiện IVehicle. Tất cả chúng đều có thể Move(), và bạn có thể viết mã không quan tâm đến loại xe mà nó đang xử lý, chỉ để nó có thể Move().

void MoveAVehicle(IVehicle vehicle) 
{ 
    vehicle.Move(); 
} 
+0

Điều đó thực sự sẽ hoạt động ngay cả khi không có giao diện. (Kiểu gõ vịt.) Giao diện chỉ làm cho bạn có thể nói với trình biên dịch ý định của bạn. – Hugo

+2

Trên thực tế, chiếc xe không phải là một giao diện, nó có thể là một lớp cơ sở. Giao diện là phù hợp hơn cho các dịch vụ hoặc tương tự, nơi bạn chỉ quan tâm đến hợp đồng và không phải là thừa kế, vì vậy tôi nghĩ rằng đa hình thực sự không phải là điều quan trọng về giao diện. – Hugo

+0

Đúng, bạn nói đúng. Nhưng thường có một giao diện định nghĩa các phương thức của lớp cha. Và trong một ý nghĩa nào đó, một giao diện là một siêu lớp, chỉ cần không thực hiện. –

51

Một ví dụ cụ thể: giao diện là một cách tốt để xác định một hợp đồng rằng mã của người khác phải đáp ứng.

Nếu tôi đang viết thư viện mã, tôi có thể viết mã hợp lệ cho các đối tượng có tập hợp hành vi nhất định. Giải pháp tốt nhất là xác định những hành vi đó trong một giao diện (không thực hiện, chỉ là một mô tả) và sau đó sử dụng các tham chiếu đến các đối tượng thực hiện giao diện đó trong mã thư viện của tôi.

Sau đó, bất kỳ người ngẫu nhiên nào có thể đi cùng, tạo một lớp thực hiện giao diện đó, khởi tạo đối tượng của lớp đó và chuyển nó vào mã thư viện của tôi và mong đợi nó hoạt động. Lưu ý: tất nhiên là có thể thực hiện nghiêm chỉnh một giao diện trong khi bỏ qua ý định của giao diện, vì vậy việc thực hiện giao diện đơn thuần là không đảm bảo rằng mọi thứ sẽ hoạt động. Ngu ngốc luôn tìm cách! :-)

Ví dụ cụ thể khác: hai nhóm làm việc trên các thành phần khác nhau phải hợp tác. Nếu hai đội ngồi xuống vào ngày thứ nhất và đồng ý trên một bộ giao diện, thì họ có thể đi theo những cách riêng của họ và thực hiện các thành phần của họ xung quanh các giao diện đó. Đội A có thể xây dựng các dây chuyền thử nghiệm mô phỏng thành phần từ Đội B để thử nghiệm và ngược lại. Phát triển song song và ít lỗi hơn.

Điểm mấu chốt là giao diện cung cấp một lớp trừu tượng để bạn có thể viết mã không biết gì về các chi tiết không cần thiết.

Ví dụ kinh điển được sử dụng trong hầu hết sách giáo khoa là phân loại thường trình. Bạn có thể sắp xếp bất kỳ lớp đối tượng nào miễn là bạn có cách so sánh bất kỳ hai đối tượng nào. Bạn có thể làm cho bất kỳ lớp nào có thể sắp xếp do đó bằng cách thực hiện giao diện IComparable, buộc bạn phải thực hiện một phương thức để so sánh hai trường hợp.Tất cả các thường trình sắp xếp được viết để xử lý các tham chiếu đến các đối tượng IComparable, vì vậy ngay sau khi bạn thực hiện IComparable, bạn có thể sử dụng bất kỳ thói quen sắp xếp nào trên các bộ sưu tập các đối tượng trong lớp của bạn.

+0

Giao diện là giải pháp "tốt nhất"? Còn thừa kế thì sao? Với một giao diện, bạn phải thực hiện mọi thành viên trong mọi lớp sử dụng nó, ngay cả khi những triển khai đó giống nhau.Với thừa kế, lớp cơ sở có thể thực hiện các thành viên chung, trong khi các lớp dẫn xuất chỉ chứa các thành viên tùy chỉnh – DOK

+3

Thừa kế có xu hướng dễ vỡ. Nếu bạn vi phạm mối quan hệ "is-a" ẩn chứa khi bạn mở rộng một siêu lớp, bạn đang yêu cầu gặp sự cố khi xuống đường. –

+0

Revah: OK, bạn cần sử dụng thừa kế một cách chính xác. Nhưng bạn phải viết (amd duy trì) nhiều hơn nữa mã trùng lặp với một giao diện so với việc có một phiên bản duy nhất của phương thức (nếu thích hợp) trong một lớp cơ sở. – DOK

0

Như bạn đã lưu ý, các giao diện là tốt cho khi bạn muốn buộc một người nào đó làm cho nó ở một định dạng nhất định.

Giao diện tốt khi dữ liệu không ở định dạng nhất định có thể có nghĩa là đưa ra các giả định nguy hiểm trong mã của bạn.

Ví dụ: tại thời điểm tôi viết một ứng dụng sẽ chuyển đổi dữ liệu từ một định dạng này sang định dạng khác. Tôi muốn buộc họ đặt những trường đó vào để tôi biết chúng sẽ tồn tại và sẽ có cơ hội được triển khai đúng cách hơn. Tôi không quan tâm nếu một phiên bản khác xuất hiện và nó không biên dịch cho chúng bởi vì có nhiều khả năng dữ liệu được yêu cầu hơn.

Giao diện hiếm khi được sử dụng vì lý do này, vì thông thường bạn có thể đưa ra giả định hoặc không thực sự yêu cầu dữ liệu để thực hiện những gì bạn cần làm.

+0

Điểm tốt về giao diện bị giòn. Bạn không thể thay đổi chúng mà không vi phạm nhiều thứ. – DOK

0

Giao diện, chỉ xác định giao diện . Sau đó, bạn có thể định nghĩa phương thức (trên các lớp khác), chấp nhận các giao diện như các tham số (hoặc chính xác hơn, đối tượng thực hiện giao diện đó). Bằng cách này, phương pháp của bạn có thể hoạt động trên nhiều đối tượng khác nhau, mà chỉ có tính phổ biến là chúng triển khai giao diện đó.

0

Đầu tiên, chúng cung cấp cho bạn lớp trừu tượng bổ sung . Bạn có thể nói "Đối với hàm này, tham số này phải là một đối tượng có các phương thức này với các tham số này". Và bạn có thể cũng muốn đặt ý nghĩa của những phương thức này, bằng cách nào đó đã được tóm tắt, nhưng vẫn cho phép bạn giải thích về mã. Trong các ngôn ngữ vịt-gõ bạn nhận được miễn phí. Không cần rõ ràng, cú pháp "giao diện". Tuy nhiên, bạn vẫn có thể tạo ra một bộ giao diện khái niệm , một cái gì đó giống như các hợp đồng (như trong Thiết kế theo Hợp đồng).

Hơn nữa, giao diện đôi khi được sử dụng cho mục đích "thuần túy" ít hơn. Trong Java, chúng có thể được sử dụng để mô phỏng nhiều thừa kế. Trong C++, bạn có thể sử dụng chúng để giảm thời gian biên dịch.

Nói chung, chúng giảm khớp nối trong mã của bạn. Đó là một điều tốt.

Mã của bạn cũng có thể dễ dàng hơn để thử nghiệm theo cách này.

8

Giao diện xác định hợp đồng và đó là từ khóa.

Bạn sử dụng giao diện khi bạn cần xác định hợp đồng trong chương trình nhưng bạn không thực sự quan tâm đến phần còn lại của thuộc tính của lớp thỏa mãn hợp đồng đó miễn là nó.

Vì vậy, hãy xem ví dụ. Giả sử bạn có một phương thức cung cấp chức năng để sắp xếp danh sách. Điều đầu tiên .. danh sách là gì? Bạn có thực sự quan tâm những yếu tố nào nó giữ để sắp xếp danh sách? Câu trả lời của bạn không phải là ... Trong .NET (ví dụ) bạn có một giao diện gọi là IList định nghĩa các hoạt động mà một danh sách PHẢI hỗ trợ để bạn không quan tâm đến các chi tiết thực sự bên dưới bề mặt.

Quay lại ví dụ, bạn không thực sự biết lớp của các đối tượng trong danh sách ... bạn cũng không quan tâm. Nếu bạn chỉ có thể so sánh các đối tượng bạn cũng có thể sắp xếp chúng.Vì vậy, bạn khai báo hợp đồng:

interface IComparable 
{ 
    // Return -1 if this is less than CompareWith 
    // Return 0 if object are equal 
    // Return 1 if CompareWith is less than this 
    int Compare(object CompareWith); 
} 

hợp đồng đó chỉ định rằng phương thức chấp nhận đối tượng và trả về int phải được thực hiện để có thể so sánh được. Bây giờ bạn đã xác định một hợp đồng và cho bây giờ bạn không quan tâm đến các đối tượng chính nó nhưng về hợp đồng vì vậy bạn chỉ có thể làm:

IComparable comp1 = list.GetItem(i) as IComparable; 

if (comp1.Compare(list.GetItem(i+1)) < 0) 
    swapItem(list,i, i+1) 

PS: Tôi biết các ví dụ là một chút ngây thơ nhưng họ là các ví dụ ...

+0

Một nit, hợp đồng 'IComparable' không xác định bạn trả về' 1', '0' và' -1' nhưng bạn trả về '> 0',' 0' và '<0'. Điều này cho phép các optimizatin như sắp xếp trên một int bằng cách thực hiện 'return this.intNum - CompareWith.intNum'. Bạn không quan tâm bao nhiêu hay ít hơn 0 nó, chỉ là thực tế là nó là nhiều hơn hoặc ít hơn. –

2

Giao diện là một dạng đa hình. Ví dụ:

Giả sử bạn muốn viết một số mã đăng nhập. Việc ghi nhật ký sẽ chuyển sang một nơi nào đó (có thể là một tệp hoặc một cổng nối tiếp trên thiết bị mà mã chính chạy trên hoặc đến một ổ cắm hoặc bị vứt bỏ như/dev/null). Bạn không biết ở đâu: người dùng mã đăng nhập của bạn cần được tự do xác định điều đó. Trong thực tế, mã đăng nhập của bạn không quan tâm. Nó chỉ muốn một cái gì đó nó có thể viết byte.

Vì vậy, bạn phát minh ra một giao diện được gọi là "thứ bạn có thể ghi byte vào". Mã đăng nhập được đưa ra một thể hiện của giao diện này (có lẽ tại thời gian chạy, có lẽ nó được cấu hình tại thời gian biên dịch. Nó vẫn là đa hình, các loại khác nhau). Bạn viết một hoặc nhiều lớp thực hiện giao diện và bạn có thể dễ dàng thay đổi nơi đăng nhập chỉ bằng cách thay đổi mã đăng nhập sẽ sử dụng. Người khác có thể thay đổi nơi đăng nhập bằng cách viết các triển khai của riêng họ về giao diện, mà không thay đổi mã của bạn. Đó là cơ bản những gì đa hình số tiền - biết chỉ đủ về một đối tượng để sử dụng nó một cách cụ thể, trong khi cho phép nó thay đổi trong tất cả các khía cạnh bạn không cần phải biết về. Giao diện mô tả những điều bạn cần biết.

Mô tả tập tin của C về cơ bản là giao diện "cái mà tôi có thể đọc và/hoặc viết byte từ và/hoặc", và hầu như mọi ngôn ngữ đã gõ đều có giao diện như vậy ẩn trong thư viện chuẩn của nó. Các ngôn ngữ không được nhập thông thường có các loại không chính thức (có thể được gọi là các hợp đồng) đại diện cho các luồng. Vì vậy, trong thực tế bạn hầu như không bao giờ phải thực sự phát minh ra giao diện cụ thể này cho mình: bạn sử dụng những gì ngôn ngữ mang lại cho bạn.

Ghi nhật ký và luồng chỉ là một ví dụ - giao diện xảy ra bất cứ khi nào bạn có thể mô tả bằng thuật ngữ trừu tượng đối tượng được phép làm gì, nhưng không muốn buộc nó vào một triển khai/lớp/cụ thể.

7

Một ví dụ điển hình là kiến ​​trúc plugin. Nhà phát triển A viết ứng dụng chính và muốn chắc chắn rằng tất cả các plugin được viết bởi nhà phát triển B, C và D phù hợp với những gì ứng dụng của anh mong đợi từ họ.

0

Giả sử bạn muốn theo dõi bộ sưu tập nội dung. Các bộ sưu tập đã nói phải hỗ trợ nhiều thứ, như thêm và xóa các mục và kiểm tra xem một mục có trong bộ sưu tập không.

Sau đó bạn có thể chỉ định giao diện ICollection với các phương thức add(), remove() và contains().

Mã không cần biết loại bộ sưu tập nào (Danh sách, Mảng, Bảng băm, Cây đỏ đen, v.v.) có thể chấp nhận các đối tượng đã triển khai giao diện và làm việc với chúng mà không biết loại thực tế của chúng.

0

Trong .Net, tôi tạo các lớp cơ sở và kế thừa từ chúng khi các lớp liên quan đến nhau. Ví dụ, lớp cơ sở Người có thể được thừa kế bởi nhân viên và khách hàng. Người có thể có các thuộc tính chung như trường địa chỉ, tên, số điện thoại, v.v. Nhân viên có thể có tài sản riêng của mình. Khách hàng có các đặc tính độc quyền khác.

Vì lớp chỉ có thể kế thừa từ một lớp khác trong .Net, tôi sử dụng giao diện cho chức năng chia sẻ bổ sung. Đôi khi các giao diện được chia sẻ bởi các lớp không có liên quan. Sử dụng giao diện tạo ra một hợp đồng mà các nhà phát triển sẽ biết được chia sẻ bởi tất cả các lớp khác đang triển khai nó. Tôi cũng buộc các lớp đó phải thực hiện tất cả các thành viên của nó.

4

Bàn đạp trên xe thực hiện giao diện. Tôi đến từ Mỹ, nơi chúng tôi lái xe ở phía bên phải của con đường. Các bánh lái của chúng tôi nằm ở phía bên trái của xe. Bàn đạp cho hộp số tay từ trái sang phải là ly hợp -> phanh -> máy gia tốc. Khi tôi đến Ireland, lái xe bị đảo ngược. Các tay lái của xe ô tô ở bên phải và họ lái xe ở bên trái đường ... nhưng bàn đạp, bàn đạp ... họ đã thực hiện cùng một giao diện ... tất cả ba bàn đạp đều theo cùng thứ tự ... vì vậy ngay cả khi lớp học khác nhau và mạng mà lớp học hoạt động trên là khác nhau, tôi vẫn cảm thấy thoải mái với giao diện bàn đạp. Não tôi có thể gọi cơ bắp của tôi trên chiếc xe này giống như mọi chiếc xe khác.

Hãy suy nghĩ về nhiều giao diện phi lập trình mà chúng tôi không thể sống thiếu. Sau đó trả lời câu hỏi của riêng bạn.

+1

Vì vậy, các loại xe Hoa Kỳ và Ô tô Anh triển khai giao diện Xe có phương pháp cho Ly hợp, Phanh và Máy gia tốc và tài sản Chỉ đạoWheelOrientation? Sau đó, các phương pháp Clutch, Brake và Accelerator về cơ bản giống hệt nhau nhưng mã của chúng phải được sao chép trong mỗi lớp thực hiện Xe hơi? – DOK

+0

Vâng, tôi không cố gắng để thực hiện tương tự tất cả các cách vào một chương trình một. OP cho biết anh ta biết họ không phải là lý do tại sao sử dụng chúng. Tôi muốn hiển thị giao diện có thể trông như thế nào trong một mục chung trong thế giới thực. Đôi khi nó bước ra ngoài thế giới tưởng tượng hiện tại của chúng tôi để nắm bắt một khái niệm. –

0

Trong một bài viết trong blog của tôi, tôi mô tả ngắn gọn ba mục đích của giao diện.

Giao diện có thể phải mục đích khác nhau:

  • Cung cấp triển khai khác nhau cho cùng một mục tiêu. Ví dụ điển hình là một danh sách, có thể có các triển khai khác nhau cho các trường hợp sử dụng hiệu suất khác nhau (LinkedList, ArrayList, v.v ...).
  • Cho phép sửa đổi tiêu chí. Ví dụ: chức năng sắp xếp có thể chấp nhận Giao diện có thể so sánh để cung cấp bất kỳ loại tiêu chí sắp xếp nào, dựa trên cùng một thuật toán.
  • Ẩn chi tiết triển khai. Điều này cũng giúp người dùng dễ dàng nhận được các chú thích , vì trong phần nội dung của giao diện chỉ có các phương thức, trường và nhận xét, không có đoạn mã dài để bỏ qua .

Dưới đây là của bài viết toàn văn: http://weblogs.manas.com.ar/ary/2007/11/

1

Hãy tưởng tượng giao diện cơ bản sau đây trong đó xác định một cơ chế cơ bản CRUD:

interface Storable { 
    function create($data); 
    function read($id); 
    function update($data, $id); 
    function delete($id); 
} 

Từ giao diện này, bạn có thể nói rằng bất kỳ đối tượng mà cụ nó, phải có chức năng để tạo, đọc, cập nhật và xóa dữ liệu. Điều này có thể do kết nối cơ sở dữ liệu, trình đọc tệp CSV và trình đọc tệp XML hoặc bất kỳ loại cơ chế nào khác có thể muốn sử dụng các hoạt động CRUD.

Vì vậy, bây giờ bạn có thể có một cái gì đó như sau:

class Logger { 
    Storable storage; 

    function Logger(Storable storage) { 
     this.storage = storage; 
    } 

    function writeLogEntry() { 
     this.storage.create("I am a log entry"); 
    } 
} 

logger này không quan tâm nếu bạn vượt qua trong một kết nối cơ sở dữ liệu, hoặc cái gì đó thao tác các tập tin trên đĩa. Tất cả những gì cần biết là nó có thể gọi create() trên nó, và nó sẽ hoạt động như mong đợi.

Câu hỏi tiếp theo phát sinh từ điều này là, nếu cơ sở dữ liệu và tệp CSV, vv, tất cả có thể lưu trữ dữ liệu không, chúng không được kế thừa từ đối tượng Storable chung và do đó không cần đến giao diện? Câu trả lời cho điều này là không ... không phải mọi kết nối cơ sở dữ liệu đều có thể triển khai các hoạt động CRUD và cũng áp dụng cho mọi trình đọc tệp.

Giao diện xác định đối tượng có khả năng làm gì và cách bạn cần sử dụng nó ... không phải là gì!

+2

"Giao diện xác định đối tượng có khả năng làm gì và bạn cần sử dụng nó như thế nào ... không phải nó là gì!" Điều này làm rõ cho tôi nhiều hơn mọi thứ khác trên trang này. –

0

Trong giao diện C# cũng cực kỳ hữu ích cho phép đa hình cho các lớp không chia sẻ cùng một lớp cơ sở. Có nghĩa là, vì chúng ta không thể có nhiều thừa kế, bạn có thể sử dụng các giao diện để cho phép các kiểu khác nhau được sử dụng. Nó cũng là một cách để cho phép bạn phơi bày các thành viên cá nhân để sử dụng mà không cần phản ánh (thực hiện rõ ràng), vì vậy nó có thể là một cách hay để thực hiện chức năng trong khi vẫn giữ mô hình đối tượng của bạn sạch sẽ.

Ví dụ:

public interface IExample 
{ 
    void Foo(); 
} 

public class Example : IExample 
{ 
    // explicit implementation syntax 
    void IExample.Foo() { ... } 
} 

/* Usage */ 
Example e = new Example(); 

e.Foo(); // error, Foo does not exist 

((IExample)e).Foo(); // success 
0

tôi nghĩ rằng bạn cần để có được một tốt hiểu các mẫu thiết kế nên thấy có sức mạnh.

Check-out Head First Design Patterns

0

Mã Java tốt nhất mà tôi đã từng nhìn thấy được xác định gần như tất cả các tài liệu tham khảo đối tượng như trường hợp của các giao diện thay vì thể hiện của lớp . Đó là một dấu hiệu mạnh mẽ của mã chất lượng được thiết kế cho sự linh hoạt và thay đổi.

5

Cách dễ nhất để hiểu giao diện là chúng cho phép các đối tượng khác nhau hiển thị chức năng COMMON. Điều này cho phép lập trình viên viết nhiều mã đơn giản hơn, ngắn hơn mà các chương trình vào một giao diện, sau đó miễn là các đối tượng thực hiện giao diện đó nó sẽ hoạt động.

Ví dụ 1: Có rất nhiều nhà cung cấp cơ sở dữ liệu khác nhau, MySQL, MSSQL, Oracle, vv Tuy nhiên tất cả các đối tượng cơ sở dữ liệu có thể làm những điều tương tự, do đó bạn sẽ tìm thấy nhiều giao diện cho các đối tượng cơ sở dữ liệu. Nếu một đối tượng thực hiện IDBConnection thì nó sẽ hiển thị các phương thức Open() và Close(). Vì vậy, nếu tôi muốn chương trình của tôi là nhà cung cấp cơ sở dữ liệu bất khả tri, tôi lập trình cho giao diện chứ không phải cho các nhà cung cấp cụ thể.

IDbConnection connection = GetDatabaseConnectionFromConfig() 
connection.Open() 
// do stuff 
connection.Close() 

Xem bằng cách lập trình để một giao diện (IDbConnection) bây giờ tôi có thể trao đổi trên bất kỳ nhà cung cấp dữ liệu trong cấu hình của tôi, nhưng mã của tôi vẫn như chính xác như vậy. Sự linh hoạt này có thể cực kỳ hữu ích và dễ bảo trì. Nhược điểm của điều này là tôi chỉ có thể thực hiện các hoạt động cơ sở dữ liệu 'chung' và có thể không tận dụng hết sức mạnh mà mỗi nhà cung cấp cụ thể cung cấp như vậy với mọi thứ trong lập trình bạn có giao dịch và bạn phải xác định kịch bản nào sẽ mang lại lợi ích cho bạn nhiều nhất.

Ví dụ 2: Nếu bạn nhận thấy gần như tất cả các bộ sưu tập triển khai giao diện này được gọi là IEnumerable. IEnumerable trả về một IEnumerator có MoveNext(), Current, và Reset(). Điều này cho phép C# dễ dàng di chuyển qua bộ sưu tập của bạn. Lý do nó có thể làm điều này là vì nó cho thấy giao diện IEnumerable nó biết rằng đối tượng phơi bày các phương thức mà nó cần phải trải qua nó. Điều này làm hai việc. 1) vòng foreach bây giờ sẽ biết làm thế nào để liệt kê các bộ sưu tập và 2) bây giờ bạn có thể áp dụng mạnh mẽ LINQ exprssions để bộ sưu tập của bạn. Một lần nữa lý do tại sao các giao diện lại hữu ích ở đây là bởi vì tất cả các bộ sưu tập đều có thứ gì đó trong COMMON, chúng có thể được chuyển qua.Mỗi bộ sưu tập có thể được chuyển qua một cách khác (danh sách liên kết so với mảng) nhưng đó là vẻ đẹp của giao diện là việc triển khai được ẩn và không liên quan đến người tiêu dùng của giao diện. MoveNext() cung cấp cho bạn mục tiếp theo trong bộ sưu tập, nó không quan trọng CÁCH nó làm điều đó. Đẹp quá nhỉ?

Ví dụ 3: Khi bạn thiết kế giao diện của riêng mình, bạn chỉ cần tự hỏi mình một câu hỏi. Những thứ này có điểm chung là gì? Một khi bạn tìm thấy tất cả những thứ mà các đối tượng chia sẻ, bạn trừu tượng hóa các thuộc tính/phương thức đó thành một giao diện để mỗi đối tượng có thể kế thừa từ nó. Sau đó, bạn có thể lập trình chống lại một số đối tượng bằng cách sử dụng một giao diện.

Và tất nhiên tôi phải đưa ra ví dụ đa hình C++ yêu thích của mình, ví dụ về động vật. Tất cả các loài động vật đều có đặc điểm nhất định. Cho phép nói rằng họ có thể di chuyển, nói chuyện, và tất cả đều có một tên. Vì tôi vừa xác định được tất cả các loài động vật của tôi có điểm chung và tôi có thể tóm tắt những phẩm chất đó vào giao diện IAnimal. Sau đó, tôi tạo ra một đối tượng Bear, một đối tượng Owl và một đối tượng Snake tất cả đều triển khai thực hiện giao diện này. Lý do tại sao bạn có thể lưu trữ các đối tượng khác nhau cùng nhau thực hiện cùng một giao diện là vì các giao diện đại diện cho một sự thay thế IS-A. Một con gấu IS-A động vật, một con vật IS-A cú, do đó, nó làm cho vì tôi có thể thu thập tất cả chúng như là Động vật.

var animals = new IAnimal[] = {new Bear(), new Owl(), new Snake()} // here I can collect different objects in a single collection because they inherit from the same interface 

foreach (IAnimal animal in animals) 
{ 
    Console.WriteLine(animal.Name) 
    animal.Speak() // a bear growls, a owl hoots, and a snake hisses 
    animal.Move() // bear runs, owl flys, snake slithers 
} 

Bạn có thể thấy rằng mặc dù những con vật này thực hiện mỗi hành động theo một cách khác, tôi có thể lập trình đối với họ tất cả trong một mô hình thống nhất và điều này chỉ là một trong nhiều lợi ích của giao diện. Vì vậy, một lần nữa điều quan trọng nhất với giao diện là những gì các đối tượng có điểm chung để bạn có thể lập trình chống lại các đối tượng DIFFERENT theo cách CÙNG. Tiết kiệm thời gian, tạo ra các ứng dụng linh hoạt hơn, ẩn tính phức tạp/triển khai, mô hình các đối tượng/tình huống trong thế giới thực, cùng với nhiều lợi ích khác.

Hy vọng điều này sẽ hữu ích.

2
When you need different classes to share same methods you use Interfaces. 
+0

Tôi có thể sử dụng thừa kế quá.There phải là một số bắt tại sao chúng ta sử dụng interface.Does nó làm cho mã của tôi đơn giản hơn, hoặc tiết kiệm một số bộ nhớ, cải thiện khả năng đọc, dễ quản lý, linh hoạt và vv? –

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