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 String LABLE="Shape";
	
	//介面方法默認為隱式抽象和公開
	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