Java 中的接口(interface)是一种特殊的抽象类,它定义了一组抽象方法和常量变量。在 Java 的面向对象编程中,接口和类一样重要,也是实现多态的重要手段之一,可以让应用程序更加灵活,方便地进行扩展。
一、接口的定义和声明
接口的定义和类定义类似,但关键字不同,关键字 interface 被用于定义接口。接口可以包含抽象方法、常量、默认方法和静态方法。
public interface MyInterface { // 抽象方法 void method1(); int method2(String str); // 常量 int MAX_VALUE = 100; }
接口中的抽象方法没有方法体,即没有实现部分,其目的是声明一组意图并需由实现者提供实现,接口中的常量需要使用关键字 “final” 来修饰。
二、接口的实现
实现了接口的类必须实现接口中定义的所有方法,并且这些方法都必须是 public 的。一个类可以同时实现多个接口,用逗号分隔开就可以。
public class MyClass implements MyInterface{ // 必须实现所有接口中的抽象方法 public void method1(){ // do something } public int method2(String str){ // do something return 0; } }
在实现接口时,可以使用 Java 8 新特性,即 default 关键字创建默认方法。默认方法可以不被实现,接口提供默认实现。通过 default 关键字,我们可以在不破坏接口的基础上给接口添加方法实现。
三、接口的应用
1、多态性
在 Java 中,接口的本质是抽象的方法集合,通过实现接口,可以在一定程度上解决 Java 继承的单一继承性问题,使得一个类可以同时具有多个超类类型,这样就实现了 Java 的多态性。
public class MyAnimal { public void move(){ System.out.println("Animal is moving"); } } public interface Fly { void fly(); } public class MyBird extends MyAnimal implements Fly{ public void fly(){ System.out.println("Bird is flying"); } } public static void main(String[] args) { MyAnimal animal = new MyBird(); animal.move(); // Animal is moving ((MyBird)animal).fly(); // Bird is flying }
通过实现 Fly 接口,MyBird 类在继承 MyAnimal 类的同时具有了新的方法 fly()。在多态的场景下,我们可以使用 Fly 接口来调用 Bird 类的方法 fly()。
2、枚举常量和常量接口
在 Java 中,枚举类型和常量接口都是接口的一种特殊形式。
常量接口:常量接口就是只含有常量的接口,这样的接口常量通常被用来定义一些公共的常量,以避免接口激增和杂乱化。
public interface MyConstants { String SITE_NAME = "www.example.com"; String DB_URL = "jdbc:mysql://localhost/test"; String USERNAME = "root"; String PASSWORD = "password"; }
枚举常量:枚举也是一种特殊的类,可以被用于定义有序的常量。每个枚举常量都是枚举类的一个实例,枚举常量可以有自己的方法和字段。
public enum MyEnum { FIRST, SECOND, THIRD; public void doSomething(){ // do something } }
3、回调函数
回调函数是一种特殊的函数,在面向对象编程中,它通常作为一个对象被传递给另一个对象。调用回调函数的对象将其自身的引用传递给被调用对象,以便被调用对象能够调用回调函数。
public interface MyOnClickListener { void onClick(View v); } public class MyButton { private MyOnClickListener listener; public void setOnClickListener(MyOnClickListener listener){ this.listener = listener; } public void doSomething(){ if(listener!=null){ listener.onClick(this); } } } public static void main(String[] args) { MyButton button = new MyButton(); button.setOnClickListener(new MyOnClickListener() { @Override public void onClick(View v) { // do something } }); button.doSomething(); }
在这个例子中,MyOnClickListener 接口就是一个回调函数。MyButton 类将自身对象引用传递给了 MyOnClickListener 类的 onClick() 方法,这样 MyOnClickListener 类就能够调用 MyButton 类的 doSomething() 方法。
4、lambda 表达式
Java 8 引入了 lambda 表达式,lambda 表达式可以用来传递代码块,并且可以由函数式接口类型的变量去接收。
public interface MyRunnable { void run(); } public static void main(String[] args) { MyRunnable r = () -> System.out.println("Hello World"); r.run(); }
在这个例子中,MyRunnable 就是一个函数式接口,lambda 表达式就是一个代码块。lambda 表达式使用箭头 (->) 将参数列表和方法体分隔开来,一般来说,箭头左侧是参数列表,箭头右侧是方法体。
四、总结
接口是 Java 编程语言中,一种支持服务的契约约束。在 Java 语言的核心和类库中,接口得到了广泛的应用,在程序设计中,尤其适合在软件分层和框架设计方面的应用。掌握接口的概念和用法,可以使 Java 程序更加灵活、扩展性更强,使得程序在面对变化时更具有适应性。