在 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中文网其他相关文章!