2009-10-03 31 views
86

Tôi chỉ đang cố gắng hiểu tại sao tất cả các trường được xác định trong Giao diện hoàn toàn là staticfinal. Ý tưởng giữ trường static có ý nghĩa với tôi vì bạn không thể có đối tượng của giao diện nhưng tại sao chúng là final (ngầm)?Tại sao tất cả các trường trong một giao diện hoàn toàn tĩnh và cuối cùng?

Bất kỳ ai biết tại sao các nhà thiết kế Java đã làm việc với các trường trong giao diện staticfinal?

Trả lời

115

Giao diện không thể có hành vi hoặc trạng thái vì giao diện chỉ định chỉ một hợp đồng tương tác, không có chi tiết triển khai. Không có hành vi nào được thực thi bằng cách không cho phép các đối tượng phương thức/constructor hoặc các khối khởi tạo static/instance. Không có trạng thái nào được thực thi bởi chỉ cho phép các trường cuối cùng tĩnh. Do đó, lớp có thể có trạng thái (trạng thái tĩnh), nhưng trạng thái cá thể không được suy ra bởi giao diện.

BTW: Hằng số trong Java được xác định bởi trường cuối cùng tĩnh (và theo quy ước, tên sử dụng UPPER_CASE_AND_UNDERSCORES).

+47

Nó không nhất thiết phải đúng là các trường cuối cùng là hằng số; đó là chỉ đảm bảo cho các loại nguyên thủy. Nói chung, từ khóa cuối cùng chỉ có nghĩa là vị trí bộ nhớ sẽ không thay đổi. – Pops

+7

Tôi không nói các trường cuối cùng là hằng số, chỉ là hằng số là các trường cuối cùng. Lưu ý rằng nó được phép đặt một trường tĩnh cuối cùng không nguyên thủy trong một giao diện. Mặc dù nội dung của trường đó có thể thay đổi, tham chiếu đến nó là không đổi. –

+1

@AdriaanKoster Bạn đã nói chính xác rằng trường cuối cùng là hằng số: * Không có trạng thái nào được thực thi bởi chỉ cho phép các hằng số. * - Câu này ngụ ý rằng tất cả các trường cuối cùng là hằng số. Bạn có thể cố gắng tiếp tục tranh luận về những từ bạn đã sử dụng, nhưng rõ ràng là tuyên bố của bạn đang bị cho thuê sai lệch. –

9

Các trường phải tĩnh vì chúng không thể trừu tượng (như các phương thức có thể). Bởi vì chúng không thể trừu tượng, những người triển khai sẽ không thể cung cấp một cách hợp lý việc thực hiện khác nhau của các trường.

Các trường phải là cuối cùng, tôi nghĩ, bởi vì các trường có thể được truy cập bởi nhiều người triển khai khác nhau cho phép chúng có thể thay đổi có thể có vấn đề (như đồng bộ hóa). Cũng để tránh nó được tái triển khai (ẩn).

Chỉ là suy nghĩ của tôi.

+0

NawMan, giải thích của bạn về "Các mối hàn phải tĩnh ..." không có ý nghĩa nhiều. Nhưng bạn đã rất đúng abt "Các lĩnh vực phải được cuối cùng ..." – peakit

+1

Tôi không nghĩ rằng ông là đúng về lý do tại sao các lĩnh vực phải được cuối cùng. Việc cho phép những người triển khai khác nhau thay đổi một trường không phải là vấn đề, vì sự thừa kế khác sẽ là vấn đề. Các lĩnh vực phải là cuối cùng, như Adriaan nói, bởi vì một giao diện, và nên, là không trạng thái. Một giao diện với trạng thái cơ bản phải là một lớp trừu tượng. –

+0

Nếu bạn có một trường 'public static' không phải là' final', findbugs sẽ khiếu nại (đúng!). –

16

Có một vài điểm che đậy ở đây:

Chỉ vì lĩnh vực trong một giao diện đang ngầm tĩnh thức không có nghĩa là họ phải có hằng số thời gian biên dịch, hoặc thậm chí không thay đổi. Bạn có thể xác định ví dụ:

interface I { 
    String TOKEN = SomeOtherClass.heavyComputation(); 
    JButton BAD_IDEA = new JButton("hello"); 
} 

(Ghi chú rằng làm điều này trong một định nghĩa chú thích có thể confuse javac, liên quan đến một thực tế là ở trên thực sự biên dịch để một initializer tĩnh.)

Ngoài ra, lý do của việc hạn chế này là phong cách hơn kỹ thuật và rất nhiều người sẽ là like to see it be relaxed.

20

LÝ DO LÀ final

Bất kỳ việc triển khai có thể thay đổi giá trị của lĩnh vực nếu không được định nghĩa là chính thức. Sau đó, họ sẽ trở thành một phần của việc thực hiện. Giao diện là một đặc tả thuần túy mà không cần thực hiện bất kỳ.

LÝ DO LÀ static

Nếu họ tĩnh, sau đó họ thuộc về giao diện, và không phải là đối tượng, cũng không phải là loại thời gian chạy của đối tượng.

2

Tôi xem xét yêu cầu rằng các trường là cuối cùng là hạn chế quá mức và lỗi của các nhà thiết kế ngôn ngữ Java. Có những lúc, ví dụ: xử lý cây, khi bạn cần phải thiết lập hằng số trong việc thực hiện được yêu cầu để thực hiện các hoạt động trên một đối tượng của kiểu giao diện. Chọn một đường dẫn mã trên lớp thực hiện là một kludge.Cách giải quyết mà tôi sử dụng là để xác định một chức năng giao diện và thực hiện nó bằng cách trả lại một chữ:

public interface iMine { 
    String __ImplementationConstant(); 
    ... 
} 

public class AClass implements iMine { 
    public String __ImplementationConstant(){ 
     return "AClass value for the Implementation Constant"; 
    } 
    ... 
} 

public class BClass implements iMine { 
    public String __ImplementationConstant(){ 
     return "BClass value for the Implementation Constant"; 
    } 
    ... 
} 

Tuy nhiên, nó sẽ đơn giản hơn, rõ ràng hơn và ít bị thực hiện khác thường sử dụng cú pháp sau:

public interface iMine { 
    String __ImplementationConstant; 
    ... 
} 

public class AClass implements iMine { 
    public static String __ImplementationConstant = 
     "AClass value for the Implementation Constant"; 
    ... 
} 

public class BClass implements iMine { 
    public static String __ImplementationConstant = 
     "BClass value for the Implementation Constant"; 
    ... 
} 
+0

Bạn dường như phàn nàn nhiều hơn về các trường đang tĩnh hơn là cuối cùng. –

0

Đặc điểm kỹ thuật, hợp đồng ... Hướng dẫn máy để truy cập trường sử dụng địa chỉ đối tượng cộng với bù trừ trường. Vì các lớp có thể thực hiện nhiều giao diện, nên không có cách nào để tạo ra trường giao diện không phải cuối cùng để có cùng độ lệch trong tất cả các lớp mở rộng giao diện này. Vì vậy, cơ chế khác nhau để truy cập trường phải được thực hiện: hai truy cập bộ nhớ (lấy trường bù trừ, nhận giá trị trường) thay vì một cộng duy trì loại bảng trường ảo (tương tự bảng ảo). Đoán họ chỉ không muốn phức tạp jvm cho chức năng có thể dễ dàng mô phỏng thông qua các công cụ hiện có (phương pháp).

Trong scala chúng ta có thể có các trường trong giao diện, mặc dù nội bộ chúng được thực hiện như tôi đã giải thích ở trên (như phương pháp).

-1

static:

Bất cứ điều gì (biến hay phương thức) đó là static trong Java có thể được gọi là Classname.variablename hoặc Classname.methodname hoặc trực tiếp. Nó không phải là bắt buộc để gọi nó chỉ bằng cách sử dụng tên đối tượng.

Trong giao diện, đối tượng không thể khai báo và static làm cho nó có thể gọi biến chỉ thông qua tên lớp mà không cần tên đối tượng.

final:

Nó giúp duy trì một giá trị không đổi cho một biến vì nó không thể được ghi đè trong lớp con của nó.

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