在 Java 中,介面充當類別必須遵守的契約。由於介面僅提供可以做什麼的知識(透過方法簽署)並且隱藏它是如何完成的(透過將實作留給那些實作介面),它實現了抽象。 什麼與如何的分離是抽象背後的核心思想。
在Java 8 中,介面的發展超越了純粹的抽象行為,支援預設 和靜態 方法來提高靈活性和向後相容性 。
這篇文章深入探討了介面、它們的主要特性以及介面和抽象類別之間的區別,並透過程式碼範例來幫助您掌握概念。
Java 中的介面指定實作類別必須遵循的一組行為(方法)。它只包含方法簽章和常數。與抽象類別相比,介面透過使一個類別能夠實現多個介面來允許多重繼承。
介面中的變數隱式是公共的、靜態的、最終的。
所有方法都是隱式公有和抽象的(Java 8 之前)。
一個類別可以實作多個介面,克服類別的單一繼承限制。
從Java 8開始,介面還可以包含預設方法和靜態方法,增強向後相容性。
package oops.interfaces; public interface InterfaceBasics { // Variables are public, static, and final by default // Initialization can only be done with declaration (No Static Blocks) // Compiler Interpretation: public static final int id = 90; int id = 90; // Abstract method (public and abstract by default) // Compiler Interpretation: public abstract void abstractMethod(); void abstractMethod(); // Default method - Introduced in Java 8 (public by default) // Compiler Interpretation: public default void concreteMethod() default void concreteMethod() { System.out.println("Concrete Method Called"); } // Static method - Introduced in Java 8 (public by default) // Compiler Interpretation: public static void staticMethod() static void staticMethod() { System.out.println("Static Method Called"); } }
1。介面中的變數:
注意:靜態最終變數可以在宣告時或在靜態區塊內初始化。但是,由於介面不允許靜態區塊,因此這些變數必須在聲明期間初始化。
2。抽象方法:
3。預設方法:
4。靜態方法:
package oops.interfaces; public interface InterfaceBasics { // Variables are public, static, and final by default // Initialization can only be done with declaration (No Static Blocks) // Compiler Interpretation: public static final int id = 90; int id = 90; // Abstract method (public and abstract by default) // Compiler Interpretation: public abstract void abstractMethod(); void abstractMethod(); // Default method - Introduced in Java 8 (public by default) // Compiler Interpretation: public default void concreteMethod() default void concreteMethod() { System.out.println("Concrete Method Called"); } // Static method - Introduced in Java 8 (public by default) // Compiler Interpretation: public static void staticMethod() static void staticMethod() { System.out.println("Static Method Called"); } }
方法存取:
使用類別實例 obj 存取預設方法 (concreteMethod()) 和重寫方法 (abstractMethod()),示範如何呼叫這兩種類型的方法。
存取介面變數:
可以使用介面名稱 (InterfaceBasics.id) 和實作類別名稱 (InterfaceBasicsImpl.id) 來存取介面變數 id。這表示介面中的靜態最終變數是繼承的,允許實作類別引用該變數。
靜態方法存取:
靜態方法 staticMethod() 只能使用介面名稱 (InterfaceBasics.staticMethod()) 來呼叫。嘗試透過實作類別 (InterfaceBasicsImpl.staticMethod()) 存取它會導致編譯時錯誤,因為介面中的靜態方法不是繼承的。
package oops.interfaces; public interface InterfaceBasics { // Variables are public, static, and final by default // Initialization can only be done with declaration (No Static Blocks) // Compiler Interpretation: public static final int id = 90; int id = 90; // Abstract method (public and abstract by default) // Compiler Interpretation: public abstract void abstractMethod(); void abstractMethod(); // Default method - Introduced in Java 8 (public by default) // Compiler Interpretation: public default void concreteMethod() default void concreteMethod() { System.out.println("Concrete Method Called"); } // Static method - Introduced in Java 8 (public by default) // Compiler Interpretation: public static void staticMethod() static void staticMethod() { System.out.println("Static Method Called"); } }
即使使用預設方法,介面仍然與抽象類別不同:
Aspect | Interface | Abstract Class |
---|---|---|
Methods | Can have abstract, default, and static methods | Can have abstract and non-abstract methods |
Variables | Only public, static, and final variables | Can have any access modifier and instance variables |
Inheritance | Supports multiple inheritance | Supports single inheritance |
Constructors | Cannot have constructors | Can have constructors |
預設方法應該僅用於擴充現有介面需要向後相容的地方。它們不能取代抽象類別。
1。介面變數可以修改嗎?
不,介面變數是隱式最終變量,這意味著它們的值一旦分配就不能更改。
package oops.interfaces; public interface InterfaceBasics { // Variables are public, static, and final by default // Initialization can only be done with declaration (No Static Blocks) // Compiler Interpretation: public static final int id = 90; int id = 90; // Abstract method (public and abstract by default) // Compiler Interpretation: public abstract void abstractMethod(); void abstractMethod(); // Default method - Introduced in Java 8 (public by default) // Compiler Interpretation: public default void concreteMethod() default void concreteMethod() { System.out.println("Concrete Method Called"); } // Static method - Introduced in Java 8 (public by default) // Compiler Interpretation: public static void staticMethod() static void staticMethod() { System.out.println("Static Method Called"); } }
2。我們可以宣告一個預設方法和靜態方法嗎?
不。 預設方法提供了可以透過實現類別覆蓋的具體實現,從而實現靈活性。相反,靜態方法屬於介面本身,不能被重寫,並提供實用功能。因此,兩者不能一起使用。
package oops.interfaces; // A class implementing the InterfaceBasics interface public class InterfaceBasicsImpl implements InterfaceBasics { // Mandatory: Override all abstract methods from the interface @Override public void abstractMethod() { System.out.println("Overridden Method Called"); } public static void main(String[] args) { InterfaceBasics obj = new InterfaceBasicsImpl(); // Calling interface's default and overridden methods obj.concreteMethod(); // Output: Default Method Called obj.abstractMethod(); // Output: Overridden Method Called // Accessing interface variables (static and final by default) // Interface variables are inherited // Possible with both interface name and implementing class name System.out.println(InterfaceBasics.id); // Output: 90 System.out.println(InterfaceBasicsImpl.id); // Output: 90 // Cannot assign a value to final variable 'id' InterfaceBasicsImpl.id = 100; // --> Compile Error // Calling static method using interface name // Cannot access using implementing class name // Interface static methods are NOT inherited InterfaceBasics.staticMethod(); // Output: Static Method Called } }
3。為什麼介面中的靜態方法不能被繼承?
靜態方法與介面本身相關聯,而不是與類別的任何特定實例相關聯,這意味著它們屬於整個介面。如果透過實作類別繼承靜態方法,則可能會導致呼叫哪個方法的歧義和混亂,特別是如果多個介面定義具有相同名稱的方法。
例如:
package oops.interfaces.example; public interface Logger { // Using a variable to store the default log file name String DEFAULT_LOG_FILE_NAME = "application.log"; // Static method to get the default log file name with configuration static String getDefaultLogFileName() { // Simulating configuration retrieval // Could be from a properties file or environment variable String logFileName = System.getenv("LOG_FILE_NAME"); // If a log file name is set in the environment, return it; // Otherwise, return the default if (logFileName != null && !logFileName.isEmpty()) { return logFileName; } else { return DEFAULT_LOG_FILE_NAME; } } } public class FileLogger implements Logger { public static void main(String[] args) { // Using the interface variable String defaultLogFile = Logger.DEFAULT_LOG_FILE_NAME; // Using the static method if ("FILE".equals(System.getenv("LOG_TYPE"))) { defaultLogFile = Logger.getDefaultLogFileName(); } System.out.println("Log file used: " + defaultLogFile); } }
透過將靜態方法僅綁定到接口,Java 保持了清晰度並避免了方法解析中的潛在衝突,從而導致了臭名昭著的多重繼承鑽石問題。
Java 中的介面透過定義實作類別必須遵守的行為,在實作抽象方面發揮著至關重要的作用。隨著 Java 8 中 default 和 靜態方法 的引入,介面變得更加強大,允許向後相容並直接在介面內提供實用方法。
但是,介面並不能取代抽象類別。當您需要為行為定義契約時,尤其是當需要多重繼承時,應該使用它們。
介面透過定義類別應該做什麼來提供抽象,而不指定如何做。
變數總是公共的、靜態的和最終的。
預設方法和靜態方法,在 Java 8 中引入,允許介面內的向後相容性和實用程式實作。
介面中的靜態方法不會被繼承,確保其用法清晰。
了解如何以及何時使用介面不僅可以提高您的編碼技能,還可以幫助您為圍繞OOP 概念和Java 設計模式的面試問題做好準備。
Java 基礎
陣列面試重點
Java 記憶體基礎
Java 關鍵字要點
集合架構重點
以上是抽象:解碼 Java 中的接口的詳細內容。更多資訊請關注PHP中文網其他相關文章!