2010-03-05 26 views
9

Tôi có đoạn mã sau:Tôi có nên đặt giao diện công khai trong một tệp riêng biệt không?

import com.apple.dnssd.*; 

public interface IServiceAnnouncer { 
    public void registerService(); 
    public void unregisterService(); 
    public boolean isRegistered(); 
} 

class HelloWorld { 
     public static void main(String[] args) { 
       System.out.println("Hello, World!"); 
     } 
} 

Mã này được lưu trong một tập tin gọi là "HelloWorld.java". Trình biên dịch Java phàn nàn về mã này. Nó viết rằng lớp IServiceAnnouncer là công khai và nó phải được khai báo trong một tệp có tên là "IServiceAnnouncer.java".

Tôi có một số câu hỏi về vấn đề này:

  1. Tại sao trình biên dịch sẽ nói rằng IServiceAnnouncer là một lớp học? Đó là một giao diện. Hoặc giao diện là một trường hợp một phần của một lớp học?

  2. Nếu tôi đặt giao diện IServiceAnnouncer trong một tệp riêng biệt gọi là "IServiceAnnouncer.java" (như trình biên dịch muốn), thì tôi có thể sử dụng nó từ "HelloWorld.java" như thế nào?

  3. public interface có nghĩa là gì? Sự khác biệt giữa giao diện công khai và giao diện công cộng là gì?

+0

Không liên quan đến câu hỏi của bạn, nhưng theo tiêu chuẩn mã hóa Java chuẩn, bạn nên đặt "I" trước giao diện. –

+1

@Steve Kuo: Lời khuyên tốt, nhưng bạn có thể có một từ. :-) http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html – trashgod

Trả lời

13

Bạn nên đặt nó trong một tệp riêng biệt. Bằng cách đó, việc trao đổi trong một triển khai khác hoặc trao đổi các giao diện (API của hệ thống) trở nên dễ dàng hơn cho người khác để chống lại mà không biết chi tiết về việc triển khai của bạn hoặc phải kéo vào các phụ thuộc liên quan.

ví dụ: triển khai các API Java thông thường - ví dụ: servlets - sẽ được thực thi mã hóa theo gói giao diện do Sun cung cấp (trong trường hợp này là javax.servlet)

Bạn có thể sử dụng nó như thế nào từ việc triển khai của mình? Bằng cách nhập nó. Điều này là không cần thiết nếu nó trong cùng một gói và bạn đang biên dịch tất cả các giao diện/triển khai của bạn cùng một lúc.

Lưu ý rằng giao diện biên dịch xuống tệp .class theo cách tương tự như triển khai (những gì bạn xác định bằng cách sử dụng class).

+3

Giao diện không cần phải công khai. Chúng có thể hữu ích trong một gói, hoặc thậm chí riêng tư trong một lớp (tôi đã làm điều này cho mẫu trạng thái). – erickson

+0

Tất nhiên! Doh. Đã sửa. Thx –

6

Bạn không có lựa chọn. Tất cả các lớp/giao diện công khai phải nằm trong các tệp có tên ClassOrInterfaceName.java.

0
  1. Vấn đề với nhiều hơn một lớp nét trong một tập tin là lỗi sau đây, mà có thể xảy ra khi sử dụng Versioning và nhiều nhà phát triển đang làm việc trên cùng một dự án:

    duplicate class: X 
    class X { 
    

    Vì vậy, nó là được ưu tiên đặt các lớp công khai (và cũng không phải là công khai, btw) trong các tệp riêng biệt. Điều này sẽ làm giảm cơ hội gặp phải những lỗi này.

  2. Nếu thư mục này nằm trong cùng một thư mục, chỉ cần sử dụng IServiceAnnouncer, nếu nó nằm trong một thư mục khác, import.

  3. public hiển thị từ tất cả các gói. Không public có nghĩa là một loại protected (trong khi từ khóa protected bị cấm, lạ huh!): Nó chỉ hiển thị trong cùng một gói. Nếu bạn không chắc chắn gói là gì, hãy xem Hướng dẫn Java.http://java.sun.com/docs/books/tutorial/java/package/packages.html

-1

1) Trình biên dịch chỉ phàn nàn rằng bạn có 2 loại cấp công khai được xác định. Bạn không thể làm điều đó trong Java. Bạn có thể lồng giao diện trong lớp của bạn nếu bạn muốn, hoặc làm cho nó không công khai (hiển thị mặc định), nhưng điều đó không quá phổ biến trong Java, và có lẽ không quá hữu ích ở đây.

2) Bạn sẽ cần phải triển khai giao diện hoặc có quyền truy cập vào đối tượng thực hiện nó.

3) Giao diện có thể hiển thị công khai hoặc mặc định (gói). Các phương thức trong giao diện không cần công cụ sửa đổi vì chúng được công khai theo mặc định.

+0

3) không đúng: không phải tất cả giao diện cấp cao nhất (không lồng nhau) đều được công khai. Chúng chỉ công khai khi được xác định công khai. Thử nó! – Pindatjuh

+0

Có, tôi đã đề cập đến khả năng hiển thị gói! – pkananen

+1

Bạn có thể định nghĩa nhiều lớp cấp cao nhất như bạn thích trong Java, chỉ là các lớp công khai phải khớp với tên của tệp, có nghĩa là bạn chỉ có thể khai báo một loại công khai cấp cao nhất trong một tệp. –

1

Trình biên dịch đang sử dụng thuật ngữ "lớp" một chút lỏng lẻo. Một thuật ngữ tổng quát hơn có thể là "loại". Tôi đoán trình biên dịch sử dụng thuật ngữ "lớp" vì nó tạo ra các tệp ".class" có cùng định dạng từ mọi khai báo kiểu (class, interfaceenum).

Giao diện không nhất thiết phải là public. Nếu nó được khai báo mà không có một công cụ sửa đổi truy cập, nó có thể được truy cập chỉ trong "gói" của nó.

Một loại Java có thể (cần) được khai báo trong một gói. Các gói là một tập hợp các kiểu Java cần được xây dựng và triển khai cùng nhau. Theo mặc định, tất cả các loại trong một gói được nhập hoàn toàn, vì vậy nếu giao diện của bạn nằm trong cùng một gói, nó sẽ có sẵn cho lớp HelloWorld.

Khi bạn không khai báo gói, loại này nằm trong gói mặc định. Vì vậy, ngay cả khi bạn chỉ đặt giao diện IServiceAnnouncer trong một tệp riêng biệt, nó sẽ có sẵn cho HelloWorld. Chỉ cần biên dịch cả hai tệp cùng một lúc.

3

Những câu trả lời này đang nhảy múa xung quanh đúng câu trả lời.

  1. Có, bạn có thể khai báo nhiều lớp trong một tệp bằng Java.
  2. Bạn không thể khai báo nhiều hơn một lớp công khai, vì:
  3. Tên của lớp công khai phải khớp với tên tệp chứa; đây là lỗi biên dịch của bạn

Java rất dễ khai báo nhiều lớp trong một tệp, mặc dù bạn có thể. Đừng làm thế.

Bạn đặt IServiceAnnouncer vào một tệp riêng biệt và nhập tên lớp trong HelloWorld.java. Bạn chỉ cần biên dịch chúng cùng một lúc, chuyển cả hai tên tệp sang javac. Đó là tất cả các công trình.

Giao diện công khai, giống như bất kỳ giao diện nào khác công khai trong Java, là một loại hiển thị và có thể sử dụng được từ bất kỳ lớp nào khác. Không có "công khai", khả năng hiển thị của nó được gọi là gói riêng tư, có nghĩa là chỉ những thứ trong cùng một gói có thể sử dụng nó.

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