在Java中,我们通过定义不同的接口来让类必须实现一些特殊的功能,例如:
interface Polygon {
public void getArea();
在这里,,Polygon就是一个接口,我们用interface关键字来声明一个接口。
getArea()方法是一个被定义在Polygon接口里的方法,所有实现这个接口的类都必须实现getArea()方法
接口中可以包含抽象方法和实例,例如:
interface Polygon {
public static final String color = "blue";
public void getArea();
}
在上面的例子中我们创建了一个Polygon接口,它包括了一个常量:color和一个抽象方法getArea()
值的一提的是,接口里所有的方法都隐含public,所有的字段都隐含puboic final static,不必在接口内指定访问修饰符,例如我们可以将上述代码写成这样:
interface Polygon {
String color = "blue";
void getArea();
}
接口中的implements关键字
像抽象类一样,我们不能创建接口的对象,然而,我们可以在其他类中实现接口,在Java中,我们使用implements关键字类实现接口,例如:
interface Polygon {
void getArea(int length ,int breadth);
}
class Rectengle implements Polygon {
public void getArea(int length,int breadth) {
System.out.println("The area of rectangle is" + length * breadth);
}
}
class Main {
public static void mian(String[] args) {
Rectangle r1 = new Rectangle();
r1.getArea(5,6);
}
}
输出:
The area of the rectangle is 30
在上面的程序中,我们创建了Polygon接口,接口中有抽象方法getArea(),这意味着任何类在实现Polygon接口时都必须提供一个getArea()方法,注意,Rectangle类是用getArea()方法类实现接口的
为什么使用接口?
现在我们已经知道了什么是接口了,现在我们来学习为什么要使用接口?
接口为(实现它的)类提供了一个必须遵守的规范。
在上面的例子中,我们用getArea()方法作为Polygon接口中的一个说明,这就好比我们设定了一个法则,我们应当获得每个Polygon的面积,所以任何实现Polygon接口的方法都必须提供getArea()方法来实现接口。
类似于抽象类,接口帮助在Java中实现抽象,在这里,我们知道getArea()方法来计算每个多边形的面积,但是对于每个多边形来说,计算每个多边形面积的方式确各不相同,因此getArea()的实现是独立于每个类的。
在Java中也支持多接口,也就是说如果一个类继承了多个类,那么它就拥有多接口。
在Java中是不支持多继承的,然而一个类却可以实现多个接口,下面我们来看看多接口的作用:
interface Line{
}
...
interface Polygon {
}
...
class Rectangle implements Line,Polygon {
}
在这里,Rectangle必须提供Line接口和Rectangle接口的多个方法的实现
接口中的静态方法和私有方法:
随着JDK8的发布,接口中也可以包含静态方法了。
和类类似,我们可以访问接口中的静态方法通过使用引用,例如:
Polygon.staticMethod();
// 即通过接口名.方法名的方式调用
JDK9发布以后,接口也支持私有方法了,现在你可以在接口中使用私有方法和私有静态方法,由于不能实例化接口,所以我们将私有方法作为辅助方法来为其他接口中的方法提供支持
接口中的default 方法:
随着JDK8的发布,接口内部引入了实现方法(默认方法),在那之前,所有的方法都是抽象的
为了在接口内部声明默认方法,我们使用default关键字,例如:
public default void getSides() {
// body of getSides
}
为什么引入默认方法?
让我们做个剧情梗概来理解为什么default 方法被引进Java
假如,我们需要向接口中添加一个新方法
我们可以很容易向接口中添加方法,然而故事还没有结束,我们所有implement这个接口的类都必须提供再提供一个方法来实现这个接口
如果有很多类都实现了这个接口,那么我们需要一个一个找出这些类,然后在类中重写这个方法,这不仅很无聊,而且在重写的过程中还容易出错
为了解决这个问题,Java引入了默认方法,默认方法可以被普通类继承,让我们举个例子来更好的理解默认方法:
interface Polygon {
void getArea();
default void getSides() {
System.out.println("I can get sides of polygon");
}
}
class Rectangle implements Polygon {
public void getArea() {
int length = 6;
int breadth = 5;
int area = length * breadth;
System.out.pritln("The area of Rectangle is" + arae);
}
public void getSides() {
System.out.println("I have four sides");
}
}
class Square implements Polygon {
public void getArea() {
int length = 5;
int area = length * length;
System.out.println("The area of Square is " + area);
}
}
class Main {
public static void mian(Stirng[] args) {
Rectangle r1 = new Rectangle();
r1.getArea();
r1.getSides();
Square s1 = new Square();
s1.getArea();
}
}
输出:
The area of the rectangle is 30
I have 4 sides
The area of the square is 25
在上面的例子中,我们创建了Polygon接口,Polygon有一个默认方法getSides() 和一个抽象方法getArea()
Rectangle类实现了Polygon接口,Rectangle提供了抽象方法getArea()的实现了和默认方法getSides的重写
我们又创建了另一个Square类也实现了Polygon接口,在这,Square类仅仅提供了抽象方法getArea()的实现
让我们来看看接口的一个更实际的应用:
// To use the sqrt function
import java.lang.Math;
interface Polygon {
void getArea();
// calculate the perimeter of a Polygon
default void getPerimeter(int... sides) {
int perimeter = 0;
for (int side: sides) {
perimeter += side;
}
System.out.println("Perimeter: " + perimeter);
}
}
class Triangle implements Polygon {
private int a, b, c;
private double s, area;
// initializing sides of a triangle
Triangle(int a, int b, int c) {
this.a = a;
this.b = b;
this.c = c;
s = 0;
}
// calculate the area of a triangle
public void getArea() {
s = (double) (a + b + c)/2;
area = Math.sqrt(s*(s-a)*(s-b)*(s-c));
System.out.println("Area: " + area);
}
}
class Main {
public static void main(String[] args) {
Triangle t1 = new Triangle(2, 3, 4);
// calls the method of the Triangle class
t1.getArea();
// calls the method of Polygon
t1.getPerimeter(2, 3, 4);
}
在上面的程序中,我们创建了Polygon接口,它包括一个默认方法getPerimeter和一个抽象方法getArea(),我们可以计算出所有多边形的周长在Polygon中,现在,所有实现Polygon的类都可以使用getPerimeter()来计算周长,但是不同的多边形计算面积的方式不同,所以getArea()没有在接口中实现,并且任何实现Polygon接口的类都必须提供getArea()方法的实现。
接口中的继承
和类类似,接口也可以继承其他接口,接口的继承用来拓展接口,例如:
interface Line {
//members of Line interface
}
interface Polygon extends Line {
//members of Polygon interface and Line interface
}
在上面的例子中,Polygon接口继承了Line接口,如果一个类实现了Polygon接口,那么这个类必须要实现这两个接口中的抽象方法
注意:接口也可以拓展多个接口类似于类继承多个接口:
interface A {
...
}
interface B {
...
}
Interface C extends A, B {
...
}