Câu hỏi Tại sao các biến giao diện tĩnh và cuối cùng theo mặc định?


Tại sao các biến giao diện tĩnh và cuối cùng theo mặc định trong Java?


215
2018-03-12 05:47


gốc


Bạn không nên đặt bất kỳ biến nào bên trong Giao diện. - cherouvim
Bởi vì các giao diện xác định các hợp đồng có thể được thực hiện theo nhiều cách khác nhau. Giá trị của một biến được thực hiện. - cherouvim
Chúng tôi chắc chắn có thể khi chúng ta biết tất cả các lớp thực hiện giao diện có một số biến không đổi (tên trường cho ví dụ). - Aniket Thakur
Có một ý tưởng hay là tạo một biến trong một lớp một thể hiện của giao diện mà lớp đó thực hiện? Tôi đã nghe điều này trước đây. - Doug Hauf
Giao diện trong java theo nguyên tắc ACID, cuối cùng vì việc chuẩn hóa trong C. @cherouvim Kiểu của biến là thực thi, một biến phải được khai báo, có hoặc không có giá trị và định nghĩa của biến là giá trị. Nếu bạn thay đổi giá trị của một biến không phải là reimplementation, định nghĩa lại của nó. - Peter Rader


Các câu trả lời:


Từ câu hỏi thường gặp về thiết kế giao diện Java của Philip Shaw:

Các biến giao diện là tĩnh vì các giao diện Java không thể được khởi tạo theo đúng nghĩa của chúng; giá trị của biến phải được gán trong một ngữ cảnh tĩnh mà không có cá thể nào tồn tại. Công cụ sửa đổi cuối cùng đảm bảo giá trị được gán cho biến giao diện là một hằng số thực mà không thể được gán lại bằng mã chương trình.

nguồn


232
2018-03-12 05:54



Lưu ý rằng các lớp trừu tượng không thể được khởi tạo "theo cách riêng của chúng" và không thể có các biến mẫu. - macias
Nếu chúng tôi cố gắng thay đổi giá trị biến trong lớp triển khai, chúng tôi sẽ gặp lỗi dưới đây. Ngoại lệ trong thread "main" java.lang.Error: Vấn đề biên dịch chưa được giải quyết: Trường cuối cùng Interface1.name không thể được gán - srinivas
Lời giải thích này cho static công cụ sửa đổi hoàn toàn giả mạo. Các biến cá thể công khai của lớp là một phần của giao diện của nó và không có lý do gì khiến chúng không được trừu tượng hóa trong một Java interface, giống như các phương thức mẫu. Nó không quan trọng là một Java interface không thể được khởi tạo trực tiếp - bạn vẫn có thể có các phiên bản của các lớp thực hiện interface và nó là hợp lý để yêu cầu họ có một biến trường hợp nào đó. Về phần final, điều đó không giải thích gì cả - nó chỉ mô tả cái gì final có nghĩa. - pyrocrasty
Các báo ở trên là tốt hơn trong bối cảnh. Lý do nó đưa ra là "biến giao diện được dự định là hằng số Java". Câu trích dẫn chỉ giải thích tại sao một hằng số như vậy sẽ là tĩnh và cuối cùng. Đó là sự thật, nhưng câu hỏi thực sự là: tại sao các biến không được phép như một phần của giao diện thực tế (ví dụ: chỉ định tên và loại thành viên không phải tư nhân phải xuất hiện trong một lớp thực hiện). Nếu họ muốn "hằng số giao diện" đặc biệt, họ có thể đã sử dụng cú pháp mới hoặc chỉ quyết định rằng bất kỳ biến nào thực sự xác định trong một giao diện là các hằng số giao diện. - pyrocrasty
Các giao diện không thể có các biến mẫu để tránh sự thừa kế nhiều vấn đề trạng thái. Xem docs.oracle.com/javase/tutorial/java/IandI/… . Một lớp không thể mở rộng nhiều hơn một lớp do cùng một lý do. - denis


Vì giao diện không có đối tượng trực tiếp, cách duy nhất để truy cập chúng là sử dụng một lớp / giao diện và do đó đó là lý do tại sao nếu biến giao diện tồn tại, nó phải là tĩnh nếu không nó sẽ không thể truy cập được vào thế giới bên ngoài. Bây giờ kể từ khi nó là tĩnh, nó có thể giữ chỉ có một giá trị và bất kỳ lớp học mà thực hiện nó có thể thay đổi nó và do đó nó sẽ được tất cả các mess.

Do đó nếu ở tất cả có một biến giao diện, nó sẽ được ngầm ngầm, cuối cùng và rõ ràng là công cộng !!!


31
2017-09-04 01:15



Tất nhiên một biến cá thể sẽ có thể truy cập được nếu nó được cho phép trong một Java interface. Một lớp sẽ thực hiện giao diện, khai báo biến cá thể (theo yêu cầu của giao diện). Phương thức khởi tạo của nó (hoặc phương thức khác) thiết lập biến cá thể. Khi một cá thể của lớp được khởi tạo, bạn sẽ có thể truy cập vào biến cá thể của nó. - pyrocrasty
Java cho phép các phương thức tĩnh với các đối tượng tồn tại trong một giao diện. Những người có thể truy cập các biến tĩnh. Họ không thể thay đổi chúng, có nghĩa là các chức năng tĩnh không thể lưu trữ bất kỳ dữ liệu nào - simpleuser


công cộng: cho khả năng truy cập trên tất cả các lớp, giống như các phương thức có trong giao diện

tĩnh: như giao diện không thể có một đối tượng, interfaceName.variableName có thể được sử dụng để tham chiếu nó hoặc trực tiếp trong variableName trong lớp thực hiện nó.

sau cùng: để biến chúng thành hằng số. Nếu 2 lớp thực hiện cùng một giao diện và bạn cho cả hai quyền thay đổi giá trị, xung đột sẽ xảy ra trong giá trị hiện tại của var, đó là lý do tại sao chỉ cho phép khởi tạo một lần.

Ngoài ra tất cả các công cụ sửa đổi này đều tiềm ẩn cho một giao diện, bạn không thực sự cần phải chỉ định bất kỳ giao diện nào trong số đó.


22
2018-04-03 16:23





(Đây không phải là một câu trả lời triết học mà là một câu trả lời thực tế). Yêu cầu cho static sửa đổi là hiển nhiên đã được trả lời bởi những người khác. Về cơ bản, vì các giao diện không thể được khởi tạo, cách duy nhất để truy cập các trường của nó là làm cho chúng trở thành một trường lớp - static.

Lý do đằng sau interface các trường tự động trở thành final (hằng số) là để ngăn chặn việc triển khai khác nhau vô tình thay đổi giá trị của biến giao diện có thể vô tình ảnh hưởng đến hành vi của các triển khai khác. Hãy tưởng tượng kịch bản bên dưới nơi interface tài sản không rõ ràng trở thành final bởi Java:

public interface Actionable {
    public static boolean isActionable = false;

    public void performAction();
}

public NuclearAction implements Actionable {

    public void performAction() {
        // Code that depends on isActionable variable
        if (isActionable) {
            // Launch nuclear weapon!!!
        }
    }
}

Bây giờ, hãy nghĩ điều gì sẽ xảy ra nếu một lớp học khác thực hiện Actionable thay đổi trạng thái của biến giao diện:

public CleanAction implements Actionable  {

    public void performAction() {
        // Code that can alter isActionable state since it is not constant
        isActionable = true;
    }
}

Nếu các lớp này được nạp trong một JVM duy nhất bởi một trình nạp lớp, thì hành vi của NuclearAction có thể bị ảnh hưởng bởi một lớp khác, CleanAction, khi nó performAction() được gọi sau CleanAction's được thực hiện (trong cùng một chủ đề hoặc cách khác), mà trong trường hợp này có thể là thảm họa (ngữ nghĩa đó là).

Vì chúng tôi không biết cách thực hiện của mỗi interface sẽ sử dụng các biến này, chúng phải được ngầm final.


9
2017-07-26 03:45





Bởi vì bất cứ điều gì khác là một phần của việc thực hiện, và các giao diện không thể chứa bất kỳ việc thực hiện nào.


8
2018-03-12 05:50



thì lý do cuối cùng là gì. - Jothi
Để chỉ ra rằng nó là một hằng số. Java không có từ khóa const. tĩnh cuối cùng là cách bạn khai báo hằng số. - Amir Afghani
Kể từ Java 8, chúng có thể chứa một triển khai thực hiện, nhưng nó rất khuyến khích không sử dụng nó nếu bạn không cần khả năng tương thích ngược. :) - codepleb


tĩnh - vì Giao diện không thể có bất kỳ cá thể nào. và cuối cùng - bởi vì chúng ta không cần phải thay đổi nó.


5
2018-03-12 05:54



"chúng tôi không cần" == "chúng tôi không được phép", không trộn lẫn ý nghĩa. - peterh


public interface A{
    int x=65;
}
public interface B{
    int x=66;
}
public class D implements A,B {
    public static void main(String[] a){
        System.out.println(x); // which x?
    }
}

Đây là giải pháp.

System.out.println(A.x); // done

Tôi nghĩ rằng đó là một trong những lý do tại sao biến giao diện là tĩnh.

Không khai báo các biến bên trong Giao diện.


3
2018-03-10 15:57



Trong thực tế, không có đặc tả "A.x" nó thậm chí sẽ không biên dịch ", vì vậy nó thực sự an toàn để sử dụng các biến (mà ngầm là public static final) trong các giao diện. - Marco
Tôi không đồng ý với câu trả lời, vì @Marco nói nó thậm chí sẽ không biên dịch. Tôi đã không tìm thấy bất kỳ bất lợi nào khác cho đến nay, có thể chỉ là bạn không thấy bằng văn bản static final trước biến thực sự là tĩnh và cuối cùng. - Micer


Java không cho phép các biến trừu tượng và / hoặc các định nghĩa hàm dựng trong các giao diện. Giải pháp: Đơn giản chỉ cần treo một lớp trừu tượng giữa giao diện của bạn và triển khai của bạn mà chỉ mở rộng lớp trừu tượng như sau:

 public interface IMyClass {

     void methodA();
     String methodB();
     Integer methodC();

 }

 public abstract class myAbstractClass implements IMyClass {
     protected String varA, varB;

     //Constructor
     myAbstractClass(String varA, String varB) {
         this.varA = varA;
         this.varB = VarB;
     }

     //Implement (some) interface methods here or leave them for the concrete class
     protected void methodA() {
         //Do something
     }

     //Add additional methods here which must be implemented in the concrete class
     protected abstract Long methodD();

     //Write some completely new methods which can be used by all subclasses
     protected Float methodE() {
         return 42.0;
     }

 }

 public class myConcreteClass extends myAbstractClass {

     //Constructor must now be implemented!
     myClass(String varA, String varB) {
         super(varA, varB);
     }

     //All non-private variables from the abstract class are available here
     //All methods not implemented in the abstract class must be implemented here

 }

Bạn cũng có thể sử dụng một lớp trừu tượng không có bất kỳ giao diện nào nếu bạn chắc chắn rằng bạn không muốn triển khai nó cùng với các giao diện khác sau này. Xin lưu ý rằng bạn không thể tạo một thể hiện của một lớp trừu tượng mà bạn PHẢI mở rộng nó trước tiên.

(Từ khóa "được bảo vệ" có nghĩa là chỉ các lớp mở rộng mới có thể truy cập các phương thức và biến này.)

spyro


2
2017-10-15 15:11





Giao diện là hợp đồng giữa hai bên là bất biến, được khắc trên đá, do đó cuối cùng. Xem Thiết kế theo hợp đồng.


1
2017-12-18 10:05





bởi vì:

Static : vì chúng ta không thể có đối tượng của giao diện nên chúng ta nên tránh sử dụng biến thành viên cấp đối tượng và nên sử dụng biến cấp lớp tức là tĩnh.

Final : để chúng ta không nên có các giá trị mơ hồ cho các biến (vấn đề kim cương - Nhiều thừa kế).

Và theo giao diện tài liệu là một hợp đồng và không phải là một thực hiện.

Tham khảo: Câu trả lời của Abhishek Jain về quora http://qr.ae/TU1dTm


1
2018-04-24 12:30





Trong Java, giao diện không cho phép bạn khai báo bất kỳ biến mẫu nào. Sử dụng một biến được khai báo trong một giao diện dưới dạng một biến mẫu sẽ trả về một lỗi thời gian biên dịch.

Bạn có thể khai báo biến cố định, sử dụng static final khác với biến thể hiện.


0
2018-04-09 18:35