Java中的接口

系统: Java中的接口是核心概念之一。Java接口是Java编程语言的核心部分,在JDK中不仅被广泛使用,而且Java设计模式中也经常用到。大多数框架都大量使用Java接口。

Java中的接口

Java中的接口提供了实现抽象的一种方式。Java接口还用于为子类定义实现的契约。例如,假设我们想创建一个由多个形状组成的图形。在这里,我们可以创建一个名为Shape的接口,并定义所有不同类型的形状对象将要实现的方法。为简单起见,我们可以只保留两个方法 – draw()用于绘制形状和getArea()用于返回形状的面积。

Java接口示例

根据上述要求,我们的Shape接口将如下所示。Shape.java

package com.journaldev.design;

public interface Shape {

	//隐式public、static和final
	public String LABLE="Shape";
	
	//接口方法隐式为抽象和public
	void draw();
	
	double getArea();
}

Java中接口的重要要点

  1. interface是用来在java中创建接口的代码。

  2. 在java中我们不能实例化一个接口。

  3. 接口提供绝对抽象性,在上一篇文章中我们了解了java中的抽象类来提供抽象性,但是抽象类可以有方法实现而接口不能。

  4. 接口不能有构造函数,因为我们不能实例化它们,接口也不能有具有方法体的方法。

  5. 默认情况下,接口的任何属性都是publicstaticfinal的,因此我们不需要为属性提供访问修饰符,但如果我们这样做,编译器也不会抱怨。

  6. 默认情况下,接口方法是隐式abstractpublic的,这是完全合理的,因为该方法没有主体,所以子类可以提供方法实现。

  7. 接口不能继承任何类,但可以继承另一个接口。public interface Shape extends Cloneable{}是接口继承另一个接口的示例。实际上,Java在接口中提供了多重继承,这意味着接口可以继承多个接口。

  8. implements关键字被类用来实现一个接口。

  9. 实现接口的类必须为其所有方法提供实现,除非它是一个抽象类。例如,我们可以在抽象类中实现上述接口,如下所示:ShapeAbs.java

    package com.journaldev.design;
    
    public abstract class ShapeAbs implements Shape {
    
    	@Override
    	public double getArea() {
    		// TODO Auto-generated method stub
    		return 0;
    	}
    
    }
    
  10. 我们应该始终尝试以接口的方式编写程序,而不是依赖具体实现,以便我们预先知道实现类将始终提供实现,如果将来有更好的实现,我们可以轻松切换。

Java接口实现示例

现在让我们看一些在Java中实现我们的Shape接口的示例。Circle.java

package com.journaldev.design;

public class Circle implements Shape {

	private double radius;

	public Circle(double r){
		this.radius = r;
	}
	
	@Override
	public void draw() {
		System.out.println("Drawing Circle");
	}
	
	@Override
	public double getArea(){
		return Math.PI*this.radius*this.radius;
	}

	public double getRadius(){
		return this.radius;
	}
}

请注意,Circle类已经实现了接口中定义的所有方法,还有一些自己的方法,比如getRadius()。接口的实现可以有多种类型的构造函数。让我们看看另一个Shape接口的实现。Rectangle.java

package com.journaldev.design;

public class Rectangle implements Shape {

	private double width;
	private double height;
	
	public Rectangle(double w, double h){
		this.width=w;
		this.height=h;
	}
	@Override
	public void draw() {
		System.out.println("Drawing Rectangle");
	}

	@Override
	public double getArea() {
		return this.height*this.width;
	}

}

请注意override注解的使用,了解Java中的注解以及在Java中覆盖方法时为什么应该始终使用override注解。下面是一个测试程序,展示了如何根据接口而不是具体实现来编写代码。ShapeTest.java

package com.journaldev.design;

public class ShapeTest {

	public static void main(String[] args) {
		
		//编程接口而不是实现
		Shape shape = new Circle(10);
		
		shape.draw();
		System.out.println("Area="+shape.getArea());
		
		//轻松切换不同的实现
		shape=new Rectangle(10,10);
		shape.draw();
		System.out.println("Area="+shape.getArea());
		}

}

上述Java接口示例程序的输出为:

Drawing Circle
Area=314.1592653589793
Drawing Rectangle
Area=100.0

Java接口的好处

  1. 接口为所有实现类提供了合同,因此最好根据接口编写代码,因为实现类不能删除我们正在使用的方法。
  2. 接口对于定义类型并在代码中创建顶级层次结构是很好的起点。
  3. 由于Java类可以实现多个接口,在大多数情况下最好将接口用作超类。

Java接口的缺点

虽然接口提供了许多优点,但它也有一些缺点。

  1. 在设计项目时,我们需要非常谨慎地选择接口方法,因为我们无法在以后的时间点添加或删除接口中的任何方法,这将导致所有实现类的编译错误。有时,这会导致我们的代码中有许多扩展基础接口的接口,这变得难以维护。

  2. 如果实现类有自己的方法,我们无法直接在代码中使用它们,因为对象的类型是一个没有这些方法的接口。例如,在上面的代码中,对于代码 shape.getRadius(),我们将会得到编译错误。为了解决这个问题,我们可以使用类型转换并像这样使用该方法:

    Circle c = (Circle) shape;
    c.getRadius();
    

    尽管类的类型转换有其缺点。

这就是我在Java接口方面的全部内容。由于我们经常使用Java接口,我们应该了解其特性。确保在设计系统时使用接口,并将其作为客户端和实现接口的子类之间的契约。更新:Java 8通过引入默认方法和静态方法的实现改变了接口的定义。有关更多详细信息,请阅读Java 8接口

Source:
https://www.digitalocean.com/community/tutorials/interface-in-java