Tại sao các biến giao diện tĩnh và cuối cùng theo mặc định trong Java?
Tại sao các biến giao diện tĩnh và cuối cùng theo mặc định trong Java?
Câu trả lời:
Từ thiết kế giao diện Java FAQ 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 cách riêng của chúng; giá trị của biến phải được gán trong ngữ cảnh tĩnh trong đó không có trường hợp 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à hằng số thực không thể được gán lại bởi mã chương trình.
static
sửa đổi này là hoàn toàn giả mạo. Các biến cá thể công khai của một lớp là một phần của giao diện của nó và không có lý do nào khiến chúng không được trừu tượng hóa trong Java interface
, giống như các phương thức cá thể. Không có vấn đề gì khi Java interface
không thể được khởi tạo trực tiếp - bạn vẫn có thể có các thể hiện của các lớp thực hiện interface
và điều hợp lý là yêu cầu chúng có một biến cá thể công khai nhất định. Về phần final
, điều đó không đưa ra một lời giải thích nào cả - nó chỉ mô tả ý final
nghĩa của nó.
Vì giao diện không có đối tượng trực tiếp, nên cách duy nhất để truy cập chúng là sử dụng lớp / giao diện và đó là lý do tại sao nếu biến giao diện tồn tại, thì nó phải tĩnh nếu không nó có thể truy cập được ở bên ngoài. Bây giờ vì nó là tĩnh, nó chỉ có thể giữ một giá trị và bất kỳ lớp nào thực hiện nó có thể thay đổi nó và do đó tất cả sẽ là mớ hỗn độn.
Do đó, nếu có một biến giao diện, nó sẽ hoàn toàn tĩnh, cuối cùng và rõ ràng là công khai !!!
interface
. Một lớp sẽ thực hiện giao diện, khai báo biến thể hiện (theo yêu cầu của giao diện). Hàm tạo của nó (hoặc phương thức khác) đặt biến thể hiện. Khi một thể hiện của lớp được khởi tạo, bạn sẽ có thể truy cập biến thể hiện của nó.
công khai : 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
static : vì 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 biếnName trong lớp thực hiện nó.
sau cùng : để làm cho chúng hằng. 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 sửa đổi này là ẩn cho một giao diện, bạn không thực sự cần phải chỉ định bất kỳ trong số chúng.
( Đâ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 static
sửa đổi là rõ ràng đã đượ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à biến chúng thành một trường lớp - static
.
Lý do đằng sau các interface
trường tự động trở thành final
(không đổi) là để ngăn các triển khai khác nhau vô tình thay đổi giá trị của biến giao diện, điều này 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 mà một thuộc interface
tính không final
được Java rõ ràng trở thành :
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ờ, chỉ cần nghĩ điều gì sẽ xảy ra nếu một lớp 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 tải 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 sauCleanAction
được thực thi (trong cùng một luồng hoặc theo cách khác), trong trường hợp này có thể là thảm họa (về mặt ngữ nghĩa là vậy).
Vì chúng ta không biết làm thế nào mỗi triển khai của một interface
sẽ sử dụng các biến này, nên chúng phải hoàn toàn final
.
Bởi vì bất cứ điều gì khác là một phần của việc triển khai và các giao diện không thể chứa bất kỳ triển khai nào.
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ĩ đó là một lý do tại sao biến giao diện là tĩnh.
Đừng khai báo các biến trong Giao diện.
static final
trước biến thực sự là tĩnh và cuối cùng.
tĩnh - bởi vì Giao diện không thể có bất kỳ trường hợp nào. và cuối cùng - bởi vì chúng ta không cần phải thay đổi nó.
bởi vì:
Static
: vì chúng ta không thể có các đối tượng của giao diện, vì vậy chúng ta nên tránh sử dụng các biến thành viên cấp đối tượng và nên sử dụng các 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 - Đa kế thừa).
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
Java không cho phép các biến trừu tượng và / hoặc các định nghĩa hàm tạo trong các giao diện. Giải pháp: 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, nó chỉ mở rộng lớp trừu tượng như vậy:
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 mà 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.
(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.)
gián điệp
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 .
Giao diện: Dịch vụ yêu cầu hệ thống.
Trong giao diện, biến được mặc định gán bởi công cụ sửa đổi truy cập công khai, tĩnh, cuối cùng . Bởi vì :
công khai: Đôi khi giao diện có thể được đặt trong một số gói khác. Vì vậy, nó cần phải truy cập vào biến từ bất cứ nơi nào trong dự án.
static: Vì lớp không đầy đủ như vậy không thể tạo đối tượng. Vì vậy, trong dự án chúng ta cần truy cập vào biến không có đối tượng để có thể truy cập với sự trợ giúp củainterface_filename.variable_name
cuối cùng: Giả sử một giao diện thực hiện bởi nhiều lớp và tất cả các lớp cố gắng truy cập và cập nhật biến giao diện. Vì vậy, nó dẫn đến sự không nhất quán của việc thay đổi dữ liệu và ảnh hưởng đến mọi lớp khác. Vì vậy, nó cần phải khai báo sửa đổi truy cập với cuối cùng.
Trong Java
, giao diện không cho phép bạn khai báo bất kỳ biến đối tượng nào. Sử dụng một biến được khai báo trong giao diện làm biến thể hiện sẽ trả về lỗi thời gian biên dịch.
Bạn có thể khai báo một biến không đổi, sử dụng biến static final
khác với biến thể hiện.
Giao diện có thể được thực hiện bởi bất kỳ lớp nào và nếu giá trị đó bị thay đổi bởi một trong các lớp triển khai thì sẽ có sự hiểu lầm cho các lớp thực hiện khác. Giao diện về cơ bản là một tham chiếu để kết hợp hai thực thể corelated nhưng khác nhau. Vì lý do đó, biến khai báo bên trong giao diện sẽ hoàn toàn là cuối cùng và cũng là tĩnh vì giao diện không thể được khởi tạo.
Hãy nghĩ về một ứng dụng web nơi bạn có giao diện được xác định và các lớp khác thực hiện nó. Vì bạn không thể tạo một thể hiện của giao diện để truy cập các biến bạn cần có một từ khóa tĩnh. Vì tĩnh của nó, bất kỳ thay đổi nào trong giá trị sẽ phản ánh đến các trường hợp khác đã triển khai nó. Vì vậy, để ngăn chặn nó, chúng tôi xác định chúng là cuối cùng.
Chỉ cần thử trong Eclipse, biến trong giao diện được mặc định là cuối cùng, vì vậy bạn không thể thay đổi nó. So với lớp cha, các biến chắc chắn có thể thay đổi. Tại sao? Theo quan điểm của tôi, biến trong lớp là một thuộc tính sẽ được thừa hưởng bởi trẻ em và trẻ em có thể thay đổi nó theo nhu cầu thực tế của chúng. Ngược lại, giao diện chỉ xác định hành vi, không thuộc tính. Lý do duy nhất để đặt các biến trong giao diện là sử dụng chúng như các hằng số liên quan đến giao diện đó. Mặc dù, đây không phải là một thực hành tốt theo đoạn trích sau:
"Đặt các hằng số trong một giao diện là một kỹ thuật phổ biến trong thời kỳ đầu của Java, nhưng bây giờ nhiều người coi đó là việc sử dụng giao diện một cách khó chịu, vì các giao diện nên xử lý các dịch vụ được cung cấp bởi một đối tượng, chứ không phải dữ liệu của nó. bởi một lớp thường là một chi tiết triển khai, nhưng việc đặt chúng trong một giao diện sẽ thúc đẩy chúng đến API công khai của lớp. "
Tôi cũng đã thử đặt tĩnh hoặc không làm cho sự khác biệt nào cả. Mã như sau:
public interface Addable {
static int count = 6;
public int add(int i);
}
public class Impl implements Addable {
@Override
public int add(int i) {
return i+count;
}
}
public class Test {
public static void main(String... args) {
Impl impl = new Impl();
System.out.println(impl.add(4));
}
}