Mang đến cho bạn hành trang là Kiến thức và Kinh nghiệm

Lựa chọn chủ đề bạn quan tâm

Cùng nhau thảo luận về các vấn đề

Hãy theo dõi chúng tôi nếu bạn thấy bổ ích

  1. Hỏi đáp IT
  2. Hỏi nhanh

Các interface (giao diện, bề mặt) trong lập trình Java.

Một interface là gì?
Ngôn ngữ Java bao gồm khái niệm về một giao diện (interface), nó chỉ đơn giản là một tập hợp có tên của các hành vi có sẵn công khai và/hoặc các phần tử dữ liệu không thay đổi mà trình triển khai thực hiện giao diện đó phải cung cấp mã lệnh. Nó không chỉ rõ các chi tiết hành vi. Về bản chất (và với trình biên dịch Java), một giao diện định nghĩa một kiểu dữ liệu mới và nó là một trong những đặc tính mạnh của ngôn ngữ này.
Các lớp khác triển khai thực hiện giao diện, có nghĩa là chúng có thể sử dụng bất kỳ các hằng số trong giao diện đó bằng tên và chúng phải chỉ rõ hành vi cho các định nghĩa phương thức trong giao diện.
Bất kỳ lớp nào trong hệ thống thứ bậc cũng có thể thực hiện một giao diện cụ thể nào đó. Điều đó có nghĩa là các lớp không liên quan nhau có thể thực hiện cùng một giao diện.

Định nghĩa giao diện
Định nghĩa một giao diện là đơn giản:

public interface interfaceName {
    final constantType
    constantName = constantValue;
    ...
    returnValueType
    methodName( arguments );
    ...
}

Một khai báo giao diện trông rất giống với một khai báo lớp, trừ việc bạn sử dụng từ khóa interface. Bạn có thể đặt tên giao diện là bất cứ thứ gì bạn muốn, miễn là tên hợp lệ, nhưng theo quy ước, các tên của giao diện nhìn giống như các tên lớp. Bạn có thể bao gồm các hằng số, các khai báo phương thức, hoặc cả hai vào trong một giao diện.
Các hằng số được định nghĩa trong một giao diện giống như các hằng số được định nghĩa trong các lớp. Các từ khóa public và static được giả định sẵn cho các hằng số được định nghĩa trong một giao diện, vì vậy bạn không cần phải gõ thêm chúng. (Từ khóa final cũng được giả định sẵn, nhưng hầu hết các lập trình viên đều gõ vào từ khóa này).
Các phương thức được định nghĩa trong một giao diện (nói chung) trông khác với các phương thức được định nghĩa trong các lớp, bởi vì các phương thức trong một giao diện không có phần triển khai thực hiện. Chúng kết thúc bằng dấu chấm phẩy sau khi khai báo phương thức và chúng không có phần thân. Bất kỳ trình thực hiện nào của giao diện có trách nhiệm cung cấp phần thân của các phương thức. Các từ khóa public và abstract được giả định sẵn cho các phương thức, vì vậy bạn không cần phải gõ thêm chúng.
Bạn có thể định nghĩa các hệ thống thứ bậc của các giao diện giống như bạn định nghĩa các hệ thống thứ bậc các lớp. Bạn làm điều này với từ khóa extends như sau:

public interface interfaceName extends superinterfaceName, ... {
    interface body...
}

Một lớp có thể là một lớp con của chỉ một lớp bậc trên, nhưng một giao diện có thể mở rộng nhiều giao diện khác tùy bạn muốn. Chỉ cần liệt kê chúng sau từ khóa extends, phân cách bằng dấu phẩy.
Dưới đây là ví dụ về một giao diện:

public interface Human {
    final String GENDER_MALE = "MALE";
    final String GENDER_FEMALE = "FEMALE";
    void move();
    void talk();
}

Triển khai thực hiện các giao diện
Để sử dụng một giao diện, bạn chỉ cần triển khai thực hiện (implement) nó, điều này có nghĩa là cung cấp hành vi cho các phương thức được định nghĩa trong giao diện. Bạn làm điều đó với từ khóa implements:

public class className extends superclassName implements
interfaceName, ... {
class body
}

Theo quy ước, mệnh đề extends (nếu có) đứng trước, tiếp theo sau là mệnh đề implements. Bạn có thể triển khai thực hiện nhiều hơn một giao diện bằng cách liệt kê các tên giao diện, phân cách bằng dấu phẩy.
Ví dụ, chúng ta có thể yêu cầu lớp Person của chúng ta thực hiện giao diện Human (nói tắt “thực hiện Human” cũng có nghĩa tương tự) như sau:

public abstract class Person implements Human {
    protected int age = 0;
    protected String firstname = "firstname";
    protected String lastname = "lastname";
    protected String gender = Human.GENDER_MALE;
    protected int progress = 0;
    public void move() {
        this.progress++;
    }
}

Khi chúng ta thực hiện giao diện, chúng ta cung cấp hành vi cho các phương thức. Chúng ta phải thực hiện các phương thức này với các chữ ký (signatures) khớp với các chữ ký trong giao diện, có thêm từ khóa bổ nghĩa quyền truy cập public. Nhưng chúng ta đã chỉ triển khai thực hiện phương thức move() trên Person. Chúng ta có cần phải thực hiện phương thức talk() không? Không, bởi vì Person là một lớp trừu tượng và từ khóa abstract được giả định sẵn cho các phương thức trong một giao diện. Điều đó có nghĩa là bất kỳ lớp trừu tượng nào triển khai thực hiện các giao diện có thể thực hiện những gì nó muốn và bỏ qua phần còn lại. Nếu nó không thực hiện một hoặc nhiều phương thức, nó chuyển giao trách nhiệm đó đến các lớp con của nó. Trong lớp Person của chúng ta, chúng ta đã chọn thực hiện move() và không thực hiện talk(), nhưng chúng ta có thể chọn không triển khai thực hiện phương thức nào cả.
Các biến cá thể trong lớp của chúng ta không được định nghĩa trong giao diện. Nhưng trong giao diện có định nghĩa một số hằng số có ích và chúng ta có thể tham khảo chúng bằng tên, trong bất kỳ lớp nào thực hiện giao diện, giống như chúng ta đã làm khi chúng ta khởi tạo biến giới tính (gender). Cũng rất thường thấy các giao diện chỉ chứa các hằng số. Nếu như vậy, bạn không cần phải thực hiện giao diện để sử dụng các hằng số đó. Đơn giản chỉ cần nhập khẩu giao diện (nếu giao diện và các lớp triển khai thực hiện ở trong cùng một gói, bạn thậm chí không cần phải làm điều đó) và tham khảo các hằng số như sau:

interfaceName.constantName
Câu trả lời

- Bạn đã sẵn sàng thảo luận về chủ đề này. Hãy bấm "Viết bình luận", bạn có thể lựa chọn sử dụng tài khoản Facebook hoặc Google++

- Vì sự phát triển của cộng đồng CNTT/CNPM tại Việt Nam!

Unknown user
No responses yet

Sử dụng các giao diện
Một giao diện định nghĩa một kiểu dữ liệu tham chiếu mới. Điều đó có nghĩa là bạn có thể tham chiếu đến một giao diện bất cứ nơi nào bạn có thể tham chiếu một lớp, chẳng hạn như khi bạn ép kiểu, như được minh họa bằng các đoạn mã sau đây của phương thức main() mà bạn có thể thêm vào lớp Adult:

public static void main(String[] args) {
    ...
    Adult anAdult = new Adult();
    anAdult.talk();
    Human aHuman = (Human) anAdult;
    aHuman.talk();
}

Cả hai cuộc gọi tới talk() sẽ hiển thị Spoke. trên màn hình. Tại sao vậy? Bởi vì một Adult là một Human một khi nó thực hiện giao diện đó. Bạn có thể ép kiểu một Adult như là một Human, sau đó gọi ra phương thức được định nghĩa bởi giao diện, cũng giống như bạn có thể ép kiểu anAdult thành Person và gọi các phương thức Person trên anAdult.
Lớp Baby cũng thực hiện Human. Một Adult không phải là một Baby và một Baby không phải là một Adult, nhưng cả hai có thể được mô tả như có kiểu Human (hoặc là kiểu Person trong hệ thống thứ bậc của chúng ta). Hãy xem xét mã này ở một nơi nào đó trong hệ thống của chúng ta:

public static void main(String[] args) {
    ...
    Human aHuman = getHuman();
    aHuman.move();
}

Human có là một Adult hoặc một Baby không?. Chúng ta không cần phải quan tâm. Cho đến khi mà mọi thứ ta nhận được từ lời gọi getPerson() là có kiểu Human, thì trên đó chúng ta có thể gọi move() và chờ đợi nó đáp ứng thích hợp. Chúng ta thậm chí không cần phải quan tâm các lớp đang triển khai thực hiện giao diện có ở trong cùng hệ thống thứ bậc hay không.

Tại sao cần dùng các giao diện?
Có ba lý do chính để sử dụng các giao diện:
* Để tạo các vùng tên gợi tả và thuận tiện.
* Để liên kết các lớp trong các hệ thống thứ bậc khác nhau.
* Để che giấu các chi tiết kiểu bên dưới khỏi mã của bạn.
Khi bạn tạo một giao diện để thu thập các hằng số liên quan, giao diện này cho bạn một tên gợi tả để sử dụng khi tham chiếu các hằng số này. Ví dụ, bạn có thể có một giao diện có tên là Language để lưu trữ các tên của các ngôn ngữ, là một chuỗi ký tự không đổi. Sau đó, bạn có thể tham chiếu các tên ngôn ngữ đó như là Language.ENGLISH và tương tự. Điều này có thể làm cho mã của bạn dễ đọc hơn.
Ngôn ngữ Java chỉ hỗ trợ thừa kế đơn (single inheritance). Nói cách khác, một lớp chỉ có thể là lớp con trực tiếp của một lớp bậc trên. Đôi khi điều này trở thành khá hạn chế. Với các giao diện, bạn có thể liên kết các lớp trong các hệ thống thứ bậc khác nhau. Đó là một đặc tính mạnh của ngôn ngữ này. Về bản chất, một giao diện đơn giản chỉ định nghĩa rõ một tập hợp các hành vi mà tất cả các trình triển khai thực hiện giao diện phải hỗ trợ. Có thể rằng mối quan hệ duy nhất sẽ tồn tại giữa các lớp đang triển khai thực hiện giao diện là chúng cùng chia sẻ các hành vi mà giao diện định nghĩa. Ví dụ, giả sử chúng ta đã có một giao diện được gọi là Mover:

public interface Mover {
    void move();
}

Bây giờ giả sử rằng Person đã mở rộng giao diện đó. Điều đó có nghĩa là bất kỳ lớp nào đang triển khai thực hiện Person cũng là một Mover. Adult và Baby sẽ đủ điều kiện. Nhưng Cat hoặc Vehicle cũng có thể sẽ như thế. Và sẽ là hợp lý khi cho rằng Mountain sẽ không như vậy. Bất kỳ lớp nào đã triển khai thực hiện Mover sẽ có hành vi move(). Một cá thể Mountain sẽ không thể có hành vi đó.
Cuối cùng, nhưng không kém quan trọng, việc sử dụng giao diện cho phép bạn bỏ qua những chi tiết của kiểu cụ thể khi bạn muốn. Nhớ lại ví dụ của chúng ta khi gọi getPerson(). Chúng ta đã không quan tâm đến cái mà chúng ta đã nhận được có kiểu là gì; chúng ta chỉ muốn nó là một thứ gì đó mà chúng ta có thể gọi move() từ đó.
Tất cả nhưng điều này là các lý do thích đáng để sử dụng các giao diện. Sử dụng một giao diện chỉ đơn giản là vì bạn có thể sử dụng chúng không phải là lý do thích đáng.
0 Lượt thích

Từ khóa tìm kiếm

Câu trả lời mới nhất

Tin tuyển dụng