(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹)
目录
Java 接口
什么是接口?
Java中的接口定义了一个引用类型来创建抽象概念。接口由类实现以提供概念的实现。
在Java 8之前,一个接口只能包含抽象方法。 Java 8允许接口具有实现的静态和默认方法。
接口通过抽象概念定义不相关类之间的关系。
例如,我们可以创建一个Person类来表示一个人,我们可以创建一个Dog类来表示一只狗。
人和狗都可以走路。这里的步行是一个抽象的概念。狗可以走,人也是这样。这里我们可以创建一个名为Walkable的接口来表示walk的概念。然后我们可以有Person类和Dog类来实现Walkable概念并提供自己的实现。 Person类实现了Walkable接口,并使人以人的方式走路。Dog类可以实现Walkable界面,使狗以狗的方式走路。
在下面我们将使用一个例子来说明为什么我们需要接口。
假设
Person
类有一个walk()方法。public interface Walkable { void walk(); } class Person implements Walkable { public Person() { } public void walk() { System.out.println("a person is walking."); } } class Dog implements Walkable { public Dog() { } public void walk() { System.out.println("a dog is walking."); } }
类可以在其声明中使用关键字implements实现一个或多个接口。
通过实现一个接口,类保证它将为接口中声明的所有方法提供一个实现,或者类将自己声明为抽象。
如果一个类实现了Walkable接口,它必须提供walk()方法的实现。
像类一样,接口定义了一个新的引用类型。
当定义一个新的接口(例如,Walkable)时,我们定义一个新的参考接口类型。
以下声明有效:
Walkable w; // w is a reference variable of type Walkable
您不能创建接口类型的对象,因为接口是定义抽象概念。以下代码无效:
new Walkable(); // A compile-time error
我们可以为一个类类型创建一个对象,但是我们可以使用一个接口类型变量来引用其类实现该接口的任何对象。
因为Person和Dog类实现了Walkable接口,所以Walkable类型的引用变量可以引用这些类的对象。
Walkable w1 = new Person(); // OK Walkable w2 = new Dog(); // OK
我们可以使用它的引用类型变量访问接口的任何成员。由于Walkable接口只有一个成员,这是walk()方法,我们可以编写如下代码:
// Let the person walk w1.walk(); // Let the dog walk w2.walk();
当调用w1上的walk()方法时,它调用Person对象的walk()方法,因为w1指的是Person对象。
当调用w2上的walk()方法时,它调用Dog对象的walk()方法,因为w2指的是Dog对象。
当使用接口类型的引用变量调用方法时,它调用它所引用的对象上的方法。
下面的代码创建了一个方法来使用interface我们的参数类型。
public class Main{
public static void main(String[] args) {
Walkable[] w = new Walkable[2];
w[0] = new Person();
w[1] = new Dog();
Walkables.letThemWalk(w);
}
}
class Walkables {
public static void letThemWalk(Walkable[] list) {
for (Walkable w : list) {
w.walk();
}
}
}
声明接口
声明接口的一般语法是
<modifiers> interface <interface-name> { Constant-Declaration Method-Declaration Nested-Type-Declaration }
接口声明以修饰符列表开头,可能为空。
像类一样,一个接口可以有一个公共或包级别的作用域。
关键字public用于指示接口具有公共范围。
缺少范围修饰符指示接口具有包级别作用域。具有包级别作用域的接口只能在其包的成员内引用。
关键字interface用于声明接口,后面是接口的名称。
接口的名称必须是有效的Java标识符。
接口体跟在其名称后面并放在大括号内。
接口的主体可以为空。以下是最简单的接口声明:
package com.w3cschool; interface Updatable { // The interface body is empty }
像类一样,一个接口有一个简单的名称和一个完全限定名。关键字interface后面的标识符是其简单名称。
接口的完全限定名称通过使用其包名称和用点分隔的简单名称形成。
在上面的示例中,Updatable是简单的名称,com.java2s.Updatable是完全限定名称。
使用接口的简单和完全限定名的规则与类的规则相同。
下面的代码声明一个名为ReadOnly的接口。它有一个公共范围。
package com.w3cschool; public interface ReadOnly { // The interface body is empty }
接口声明总是抽象的,无论是否明确声明它是抽象的。
实现接口
当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。
类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面。
实现一个接口的语法,可以使用这个公式:
...implements 接口名称[, 其他接口名称, 其他接口名称..., ...] ...
/* 文件名 : MammalInt.java */
public class MammalInt implements Animal{
public void eat(){
System.out.println("Mammal eats");
}
public void travel(){
System.out.println("Mammal travels");
}
public int noOfLegs(){
return 0;
}
public static void main(String args[]){
MammalInt m = new MammalInt();
m.eat();
m.travel();
}
}
运行结果如下:
Mammal eats Mammal travels
重写接口中声明的方法时,需要注意以下规则:
- 类在实现接口的方法时,不能抛出强制性异常,只能在接口中,或者继承接口的抽象类中抛出该强制性异常。
- 类在重写方法时要保持一致的方法名,并且应该保持相同或者相兼容的返回值类型。
- 如果实现接口的类是抽象类,那么就没必要实现该接口的方法。
在实现接口的时候,也要注意一些规则:
- 一个类可以同时实现多个接口。
- 一个类只能继承一个类,但是能实现多个接口。
- 一个接口能继承另一个接口,这和类之间的继承比较相似。
继承接口
一个接口能继承另一个接口,和类之间的继承方式比较相似。接口的继承使用extends关键字,子接口继承父接口的方法。
下面的Sports接口被Hockey和Football接口继承:
// 文件名: Sports.java public interface Sports { public void setHomeTeam(String name); public void setVisitingTeam(String name); } // 文件名: Football.java public interface Football extends Sports { public void homeTeamScored(int points); public void visitingTeamScored(int points); public void endOfQuarter(int quarter); } // 文件名: Hockey.java public interface Hockey extends Sports { public void homeGoalScored(); public void visitingGoalScored(); public void endOfPeriod(int period); public void overtimePeriod(int ot); }
Hockey接口自己声明了四个方法,从Sports接口继承了两个方法,这样,实现Hockey接口的类需要实现六个方法。
相似的,实现Football接口的类需要实现五个方法,其中两个来自于Sports接口。
接口的多继承
在Java中,类的多继承是不合法,但接口允许多继承。
在接口的多继承中extends关键字只需要使用一次,在其后跟着继承接口。 如下所示:
public interface Hockey extends Sports, Event
以上的程序片段是合法定义的子接口,与类不同的是,接口允许多继承,而 Sports及 Event 可以定义或是继承相同的方法
标记接口
最常用的继承接口是没有包含任何方法的接口。
标记接口是没有任何方法和属性的接口.它仅仅表明它的类属于一个特定的类型,供其他代码来测试允许做一些事情。
标记接口作用:简单形象的说就是给某个对象打个标(盖个戳),使对象拥有某个或某些特权。
例如:java.awt.event 包中的 MouseListener 接口继承的 java.util.EventListener 接口定义如下:
package java.util; public interface EventListener {}
没有任何方法的接口被称为标记接口。标记接口主要用于以下两种目的:
- 建立一个公共的父接口:
正如EventListener接口,这是由几十个其他接口扩展的Java API,你可以使用一个标记接口来建立一组接口的父接口。例如:当一个接口继承了EventListener接口,Java虚拟机(JVM)就知道该接口将要被用于一个事件的代理方案。
- 向一个类添加数据类型:
这种情况是标记接口最初的目的,实现标记接口的类不需要定义任何接口方法(因为标记接口根本就没有方法),但是该类通过多态性变成一个接口类型。