Định nghĩa của "giao diện" trong lập trình hướng đối tượng là gì


108

Ok, một người bạn của tôi nói đi xem lại "giao diện" nghĩa là gì trong lập trình.

Mô tả tốt nhất về một "giao diện" là gì.

Đối với tôi, giao diện là bản thiết kế của một lớp, đây có phải là định nghĩa tốt nhất không?


1
không phải là một bản dupe, nhưng nó làm sáng tỏ rất nhiều câu hỏi này: stackoverflow.com/questions/444245/…
rmeador

Tôi sẽ nói đó là một từ chung chung, nhưng vẫn có nghĩa tương tự đối với tôi. Nó giống như một bức tường cho một thực thể cụ thể hoặc trừu tượng hơn cung cấp một số điểm đầu vào cho bên ngoài và cung cấp cho chúng đầu ra mà không cần bất kỳ kiến ​​thức nào về hoạt động bên trong. Tôi nghĩ rằng nó có thể được gọi là một sự trừu tượng để xác định các lớp cấp thấp hơn đến cao hơn trong OOP.
ikbal

Câu trả lời:


179

Giao diện là một trong những thuật ngữ quá tải và khó hiểu trong quá trình phát triển.

Nó thực sự là một khái niệm trừu tượng và đóng gói. Đối với một "hộp" đã cho, nó khai báo "đầu vào" và "đầu ra" của hộp đó. Trong thế giới phần mềm, điều đó thường có nghĩa là các hoạt động có thể được gọi trên hộp (cùng với các đối số) và trong một số trường hợp là kiểu trả về của các hoạt động này.

Những gì nó không làm là xác định ngữ nghĩa của các hoạt động này là gì, mặc dù thông thường (và thực tế rất tốt) là ghi lại chúng gần với khai báo (ví dụ: thông qua nhận xét) hoặc chọn các quy ước đặt tên tốt. Tuy nhiên, không có gì đảm bảo rằng những ý định này sẽ được tuân theo.

Đây là một phép tương tự: Hãy nhìn vào tivi của bạn khi nó tắt. Giao diện của nó là các nút có, các phích cắm khác nhau và màn hình. Ngữ nghĩa và hành vi của nó là nó nhận đầu vào (ví dụ: lập trình cáp) và có đầu ra (hiển thị trên màn hình, âm thanh, v.v.). Tuy nhiên, khi bạn nhìn vào một TV không được cắm điện, bạn đang chiếu ngữ nghĩa mong đợi của mình vào một giao diện. Tất cả những gì bạn biết, TV chỉ có thể phát nổ khi bạn cắm điện. Tuy nhiên, dựa trên "giao diện" của nó, bạn có thể cho rằng TV sẽ không pha cà phê vì nó không có ống hút nước.

Trong lập trình hướng đối tượng, giao diện thường xác định tập hợp các phương thức (hoặc thông báo) mà một thể hiện của lớp có giao diện đó có thể phản hồi.

Điều làm tăng thêm sự nhầm lẫn là trong một số ngôn ngữ, như Java, có một giao diện thực tế với ngữ nghĩa ngôn ngữ cụ thể của nó. Ví dụ, trong Java, nó là một tập hợp các khai báo phương thức, không có triển khai, nhưng một giao diện cũng tương ứng với một kiểu và tuân theo các quy tắc nhập khác nhau.

Trong các ngôn ngữ khác, như C ++, bạn không có giao diện. Bản thân một lớp định nghĩa các phương thức, nhưng bạn có thể coi giao diện của lớp đó là các khai báo của các phương thức không riêng tư. Do cách biên dịch C ++, bạn nhận được các tệp tiêu đề mà bạn có thể có "giao diện" của lớp mà không cần triển khai thực tế. Bạn cũng có thể bắt chước các giao diện Java với các lớp trừu tượng với các hàm ảo thuần túy, v.v.

Một giao diện chắc chắn không phải là một bản thiết kế cho một lớp. Một bản thiết kế, theo một định nghĩa là một "kế hoạch chi tiết của hành động". Một giao diện không hứa hẹn gì về một hành động! Nguồn gốc của sự nhầm lẫn là trong hầu hết các ngôn ngữ, nếu bạn có một kiểu giao diện xác định một tập hợp các phương thức, thì lớp triển khai nó sẽ "lặp lại" các phương thức giống nhau (nhưng cung cấp định nghĩa), vì vậy giao diện trông giống như một khung hoặc một dàn ý của lớp.


Tôi đang đọc một cuốn sách về Objective-C và đối với tôi, dường như các tác giả sử dụng thuật ngữ "giao thức" và "giao diện" thay thế cho nhau. Có đúng không khi nói rằng "giao thức" và "giao diện" là một thứ giống nhau hay tôi đang thiếu thứ gì đó?
Fazzolini

1
Tôi sẽ không sử dụng từ "giao thức" cho "giao diện". Từ "giao thức" ngụ ý mức độ chi tiết về cách các hành động được thực hiện. "Giao diện" thực sự là một từ xuất sắc với một định nghĩa thuần Anh mô tả chính xác nó là gì.
OCDev

Trong Windows, các giao diện lập trình được sử dụng khá rộng rãi, vì vậy ngay cả trong C ++ bạn cũng có thể gặp các "giao diện" theo cách các đối tượng được tách ra khỏi quá trình thực hiện.
Victoria

166

Hãy xem xét tình huống sau:

Bạn đang ở giữa một căn phòng rộng lớn trống trải thì một con zombie bất ngờ tấn công bạn.

Bạn không có vũ khí.

May mắn thay, một đồng loại đang sống ở ngưỡng cửa của căn phòng.

"Nhanh chóng!" bạn hét vào mặt anh ta. "Ném cho tôi thứ gì đó tôi có thể đánh thây ma!"

Bây giờ hãy xem xét:
Bạn đã không xác định (cũng như không quan tâm) chính xác những gì bạn của bạn sẽ chọn để tung;
... Nhưng điều đó không quan trọng, miễn là:

  • Đó là thứ thể ném được (Anh ấy không thể quăng ghế sofa cho bạn)

  • Đó là thứ mà bạn có thể nắm giữ (Hãy hy vọng anh ấy không ném shuriken)

  • Đó là thứ bạn có thể sử dụng để đánh bại bộ não của thây ma (Điều đó loại trừ gối và những thứ tương tự)

Không quan trọng là bạn có được một cây gậy bóng chày hay một cái búa -
miễn là nó thực hiện được ba điều kiện của bạn, bạn sẽ giỏi.

Tóm lại:

Khi bạn viết một giao diện, về cơ bản bạn đang nói: "Tôi cần một cái gì đó ..."


13
Trên thực tế, một chiếc gối sẽ vẫn hoạt động. Bạn có thể đánh thây ma bằng nó. Đập não của zombie ra ngoài ... đó là một câu hỏi về hiệu suất, không bao giờ là một phần của giao diện.
meustrus

35

Giao diện là một hợp đồng bạn phải tuân thủ hoặc được trao, tùy thuộc vào việc bạn là người triển khai hay người dùng.


1
Tôi thực sự không thích hợp đồng có thời hạn không đủ tiêu chuẩn ở đây, bởi vì hợp đồng thường bao hàm ngữ nghĩa hoặc hành vi (như trong thiết kế của hợp đồng). Không phải tất cả các giao diện đều ngụ ý bất kỳ ngữ nghĩa hoặc hành vi nào. Ví dụ, một "lỗ trên tường" là một giao diện trong thế giới thực. Bạn coi đây là cửa sổ hay là nơi xử lý rác hay bất cứ thứ gì là do bạn hiểu.
Uri

3
Thật. Giao diện là một "hợp đồng chữ ký phương thức", có nghĩa là nó đảm bảo thực hiện các phương thức đã cho. Nó không đảm bảo liệu nó có làm như vậy theo bất kỳ cách nào hay không.
Erik Funkenbusch

Chính xác, bạn nên giải thích thêm cho định nghĩa này. Nhưng giao diện là một hợp đồng giữa hai phần. Mã theo hợp đồng .... +1
matiasnj

18

Tôi không nghĩ rằng "bản thiết kế" là một từ hay để sử dụng. Bản thiết kế cho bạn biết cách xây dựng một thứ gì đó. Một giao diện đặc biệt tránh cho bạn biết cách tạo thứ gì đó.

Giao diện xác định cách bạn có thể tương tác với một lớp, tức là nó hỗ trợ những phương thức nào.


1
Tôi tin rằng người yêu cầu hỏi định nghĩa là gì và không phải định nghĩa là gì. :)
Eugene Kuleshov

7

Đối với tôi, giao diện là bản thiết kế của một lớp, đây có phải là định nghĩa tốt nhất không?

Không. Một bản thiết kế thường bao gồm phần bên trong. Nhưng một giao diện hoàn toàn là về những gì có thể nhìn thấy bên ngoài của một lớp ... hay chính xác hơn là một họ các lớp thực hiện giao diện.

Giao diện bao gồm các chữ ký của các phương thức và giá trị của các hằng số, và cũng là một "hợp đồng hành vi" (thường không chính thức) giữa các lớp triển khai giao diện và các lớp khác sử dụng nó.


6

Trong Lập trình, một giao diện xác định hành vi mà một đối tượng sẽ có, nhưng nó sẽ không thực sự chỉ định hành vi. Đó là một hợp đồng, điều đó sẽ đảm bảo, rằng một lớp nào đó có thể làm được điều gì đó.

Hãy xem xét đoạn mã C # này ở đây:

using System;

public interface IGenerate
{
    int Generate();
}

// Dependencies
public class KnownNumber : IGenerate
{
    public int Generate() 
    {
        return 5;
    }   
}

public class SecretNumber : IGenerate
{
    public int Generate()
    {
        return new Random().Next(0, 10);
    }
}

// What you care about
class Game
{
    public Game(IGenerate generator) 
    {
        Console.WriteLine(generator.Generate())
    }
}

new Game(new SecretNumber());
new Game(new KnownNumber());

Lớp Trò chơi yêu cầu một số bí mật. Để kiểm tra nó, bạn muốn đưa những gì sẽ được sử dụng làm số bí mật (nguyên tắc này được gọi là Inversion of Control).

Lớp trò chơi muốn "cởi mở" về những gì sẽ thực sự tạo ra số ngẫu nhiên, do đó nó sẽ hỏi trong hàm tạo của nó "bất kỳ thứ gì có phương thức Tạo".

Đầu tiên, giao diện chỉ định những hoạt động mà một đối tượng sẽ cung cấp. Nó chỉ chứa những gì nó trông như thế nào, nhưng không có triển khai thực tế nào được đưa ra. Đây chỉ là chữ ký của phương thức. Thông thường, trong các giao diện C # được bắt đầu bằng chữ I. Các lớp hiện triển khai Giao diện IGenerate. Điều này có nghĩa là trình biên dịch sẽ đảm bảo rằng cả hai đều có một phương thức, trả về một int và được gọi Generate. Trò chơi hiện đang được gọi là hai đối tượng khác nhau, mỗi đối tượng trong số đó có giao diện chính xác. Các lớp khác sẽ tạo ra lỗi khi xây dựng mã.

Ở đây tôi nhận thấy sự tương tự về kế hoạch chi tiết mà bạn đã sử dụng:

Một lớp thường được coi là bản thiết kế cho một đối tượng. Giao diện chỉ định một cái gì đó mà một lớp sẽ cần phải làm, vì vậy người ta có thể tranh luận rằng nó thực sự chỉ là một bản thiết kế cho một lớp, nhưng vì một lớp không nhất thiết cần một giao diện, tôi sẽ tranh luận rằng phép ẩn dụ này đang phá vỡ. Hãy nghĩ về một giao diện như một hợp đồng. Lớp "ký tên vào nó" sẽ được yêu cầu hợp pháp (được thực thi bởi cảnh sát biên dịch), tuân thủ các điều khoản và điều kiện trong hợp đồng. Điều này có nghĩa là nó sẽ phải làm, những gì được chỉ định trong giao diện.

Tất cả là do bản chất được nhập tĩnh của một số ngôn ngữ OO, như trường hợp của Java hoặc C #. Mặt khác, trong Python, một cơ chế khác được sử dụng:

import random

# Dependencies
class KnownNumber(object):
    def generate(self):
        return 5

class SecretNumber(object):
    def generate(self):
        return random.randint(0,10)

# What you care about
class SecretGame(object):
    def __init__(self, number_generator):
        number = number_generator.generate()
        print number

Ở đây, không có lớp nào triển khai giao diện. Python không quan tâm đến điều đó, bởi vì SecretGamelớp sẽ chỉ cố gắng gọi bất kỳ đối tượng nào được truyền vào. Nếu đối tượng CÓ phương thức create (), mọi thứ đều ổn. Nếu không: KAPUTT! Lỗi này sẽ không được nhìn thấy trong thời gian biên dịch, nhưng trong thời gian chạy, vì vậy có thể khi chương trình của bạn đã được triển khai và chạy. C # sẽ thông báo cho bạn trước khi bạn đến gần điều đó.

Lý do cơ chế này được sử dụng, nói một cách ngây thơ, bởi vì trong các ngôn ngữ OO, các chức năng tự nhiên không phải là công dân hạng nhất. Như bạn có thể thấy, KnownNumbervà chỉ SecretNumberchứa các hàm để tạo ra một số. Người ta không thực sự cần các lớp học. Do đó, trong Python, người ta có thể vứt bỏ chúng và tự chọn các hàm:

# OO Approach
SecretGame(SecretNumber())
SecretGame(KnownNumber())

# Functional Approach

# Dependencies
class SecretGame(object):
    def __init__(self, generate):
        number =  generate()
        print number

SecretGame(lambda: random.randint(0,10))
SecretGame(lambda: 5)

Một lambda chỉ là một hàm, được khai báo "thẳng hàng, khi bạn di chuyển". Một ủy nhiệm giống nhau trong C #:

class Game
{
    public Game(Func<int> generate) 
    {
        Console.WriteLine(generate())
    }
}    

new Game(() => 5);
new Game(() => new Random().Next(0, 10));

Lưu ý: Các ví dụ sau không thể thực hiện như thế này đối với Java 7. Ở đó, Giao diện là cách duy nhất của bạn để xác định hành vi này. Tuy nhiên, Java 8 đã giới thiệu các biểu thức lambda nên ví dụ C # có thể được chuyển đổi sang Java rất dễ dàng ( Func<int>trở thành java.util.function.IntSupplier=>trở thành ->).


4

Về mặt kỹ thuật, tôi sẽ mô tả một giao diện như một tập hợp các cách (phương thức, thuộc tính, trình truy cập ... từ vựng phụ thuộc vào ngôn ngữ bạn đang sử dụng) để tương tác với một đối tượng. Nếu một đối tượng hỗ trợ / triển khai một giao diện, thì bạn có thể sử dụng tất cả các cách được chỉ định trong giao diện để tương tác với đối tượng này.

Về mặt ngữ nghĩa, một giao diện cũng có thể chứa các quy ước về những gì bạn có thể làm hoặc không thể làm (ví dụ: thứ tự mà bạn có thể gọi các phương thức) và về những gì, đổi lại, bạn có thể giả định về trạng thái của đối tượng do cách bạn tương tác. xa.


2

Cá nhân tôi thấy một giao diện giống như một mẫu. Nếu một giao diện chứa định nghĩa cho các phương thức foo () và bar (), thì bạn biết mọi lớp sử dụng giao diện này đều có các phương thức foo () và bar ().


2

Chúng ta hãy xem xét một Người (Người dùng hoặc Đối tượng) muốn một số công việc được thực hiện. Anh ta sẽ liên hệ với một người trung gian (Giao diện), người sẽ có hợp đồng với các công ty (các đối tượng trong thế giới thực được tạo ra bằng cách sử dụng các lớp được triển khai). Anh ta sẽ xác định được ít loại công trình nào sẽ thực hiện và mang lại kết quả cho anh ta. Mỗi công ty sẽ triển khai công việc theo cách riêng của mình nhưng kết quả sẽ giống nhau. Giống như người dùng này sẽ hoàn thành công việc của mình bằng một giao diện duy nhất. Tôi nghĩ Giao diện sẽ hoạt động như một phần hiển thị của hệ thống với ít lệnh sẽ được xác định bên trong bởi các hệ thống con bên trong đang triển khai.


1

Một giao diện phân tách các hoạt động trên một lớp khỏi việc thực hiện bên trong. Do đó, một số triển khai có thể cung cấp cho nhiều giao diện.

Mọi người thường mô tả nó như một "hợp đồng" cho những gì phải có trong các phương thức của lớp.

Nó hoàn toàn không phải là một kế hoạch chi tiết, vì điều đó cũng sẽ quyết định việc thực hiện. Một định nghĩa lớp đầy đủ có thể được coi là một bản thiết kế.


1

Một giao diện xác định những gì một lớp kế thừa từ nó phải triển khai. Bằng cách này, nhiều lớp có thể kế thừa từ một giao diện và do tính kế thừa đó, bạn có thể

  • đảm bảo rằng tất cả các thành viên của giao diện được triển khai trong lớp dẫn xuất (ngay cả khi nó chỉ để ném một ngoại lệ)
  • Tóm tắt bản thân lớp khỏi trình gọi (truyền một thể hiện của lớp tới giao diện và tương tác với nó mà không cần biết IS của lớp dẫn xuất thực tế là gì)

để biết thêm thông tin, hãy xem http://msdn.microsoft.com/en-us/library/ms173156.aspx này


1

Theo ý kiến ​​của tôi, giao diện có nghĩa rộng hơn so với nghĩa thường được kết hợp với nó trong Java. Tôi sẽ định nghĩa "giao diện" là một tập hợp các hoạt động có sẵn với một số chức năng phổ biến, cho phép điều khiển / giám sát một mô-đun.

Trong định nghĩa này, tôi cố gắng bao gồm cả giao diện chương trình, trong đó máy khách là một số mô-đun và giao diện người (GUI chẳng hạn).

Như những người khác đã nói, một giao diện luôn có một số hợp đồng đằng sau nó, về đầu vào và đầu ra. Giao diện không hứa hẹn bất cứ điều gì về "cách thức" của các hoạt động; nó chỉ đảm bảo một số thuộc tính của kết quả, với trạng thái hiện tại, hoạt động đã chọn và các tham số của nó.


1

Như trên, các từ đồng nghĩa của "hợp đồng" và "giao thức" là phù hợp.

Giao diện bao gồm các phương thức và thuộc tính mà bạn có thể mong đợi được hiển thị bởi một lớp.

Vì vậy, nếu một lớp Cheetos Bagtriển khai Chip Baggiao diện, bạn sẽ mong đợi một lớp Cheetos Baghoạt động giống hệt như bất kỳ lớp nào khác Chip Bag. (Nghĩa là, phơi bày .attemptToOpenWithoutSpillingEverywhere()phương pháp, v.v.)


1

Định nghĩa thông thường - Giao diện là một hợp đồng xác định các phương thức cần được thực hiện bởi lớp thực thi nó.

Định nghĩa về Giao diện đã thay đổi theo thời gian. Bạn có nghĩ rằng Giao diện chỉ có khai báo phương thức mà thôi? Điều gì về các biến cuối cùng tĩnh và những gì về các định nghĩa mặc định sau Java 5.

Các giao diện đã được đưa vào Java do vấn đề Kim cương với nhiều Thừa kế và đó là những gì họ thực sự định làm.

Giao diện là các cấu trúc được tạo ra để giải quyết vấn đề đa kế thừa và có thể có các phương thức trừu tượng, định nghĩa mặc định và các biến cuối cùng tĩnh.

http://www.quora.com/Why-does-Java-allow-static-final-variables-in-interfaces-when-they-are-only-intended-to-be-contracts



Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.