Java接口

1 接口概念

  1. 接口的概念與使用方法
  • 接口不是類,而是對類的一組需求描述,這些類要遵從接口描述的統一格式定義方法。
    例如:如果要使用Arrays.sort方法,那麼對象所屬的類必須實現了Comparable接口。
  • 接口不能包含成員變量,只能包含方法和常量。
  • Java SE8之後可以在接口中提供簡單方法,這些方法不能引用成員變量。
  • 實現接口的步驟如下:
    1)將類聲明爲實現給定的接口。
    2)對接口中的方法進行定義。
class Employee implements Comparable{
	public int compareTo(Object otherObject){
	}
}
  • 可以爲泛型接口提供參數
class Employee implements Comparable<Employee>{
}
  1. 接口的特性
  • 接口不是類,不能使用new運算符實例化,但是可以聲明接口的變量,接口變量必須引用實現了接口的類對象
Comparable x;
  • 可以使用instanceof檢查一個對象是否實現了某個特定接口:
if(anObject instanceof Comparable){
}
  1. 接口與抽象類
  • 爲什麼不用抽象類來代替接口呢?Java中一個類只能有一個父類,但可以有多個接口。如果一個類要繼承多個抽象類的方法,使用抽象類就不行了。
    在C++中允許多重繼承。但也由此帶來了一系列複雜特性和效率問題。
  1. 靜態方法
  • Java SE8中允許在接口中添加靜態方法,但通常的做法是將靜態方法放在伴隨類中,在標準庫中可以看到成對出現的接口和實用工具類,如Path/Paths。
  • 現在可以爲Path接口添加方法,那樣Paths類就沒有存在的意義了,但要改寫整個標準庫是不可能的。因此伴隨類的方法還很有用。只是自己實現方法時不再需要另外寫一個伴隨類。
  1. 默認方法
  • 可以爲接口方法提供一個默認實現,需要用default修飾符標記此方法。
  • 在Java SE8中,可以爲接口的所有方法提供默認方法,這樣程序員只需要關心他們需要的方法。
  • 以前的版本不支持默認方法,如果爲接口添加了新方法,那麼老的代碼的類由於沒有實現此方法會無法通過編譯,解決辦法是將新增方法設爲默認方法
  1. 解決默認方法衝突
  • 超類優先:如果在類的超類和接口中有同名方法,那麼超類的方法優先。因此千萬不能讓默認方法重定義Object類中的方法,由於超類優先原則,這樣做將沒有任何意義。
  • 接口衝突:如果一個類包含了多個接口有同名方法,且至少有一個接口的方法有默認實現,那麼就必須覆蓋此方法而不能使用默認方法,可以在覆蓋的方法中再選擇調用某個接口的默認方法。
class Student implements Person,Named
{
	public String getName()
	{
		return Person.super.getName();
	}
}

2 接口示例

  1. 監聽接口
    Java中的消息響應函數需要通過接口來實現,例如Timer類定時器,在構造時需要傳入一個包含了ActionListener接口的對象,定時調用其actionPerformed方法。示例:
package alarmClock;

import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JOptionPane;
import javax.swing.Timer;

public class TimerTest {
	public static void main(String[] args) {
		ActionListener listener=new TimePrinter();
		Timer timer=new Timer(10000, listener);
		timer.start();
		JOptionPane.showMessageDialog(null, "123");//用來彈出一個對話框,不要點ok,防止程序過早結束,看不到結果。
		System.exit(0);
	}
}

class TimePrinter implements ActionListener{

	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		System.out.println("Ding");
		Toolkit.getDefaultToolkit().beep();
	}
}

  1. Comparator接口
    假如我們想要按照字符串的長度對String對象進行排序而不是字典順序,String類又不允許我們覆蓋,該怎麼辦呢。
    Array.sorts方法提供了第二個版本,一個數組和一個比較器,比較器是實現了Comparator接口的類的實例。
    類似於STL中的傳入仿函數的辦法。
//Comparator接口的定義
public interface Comparator<T>
{
	int compare(T first,T second);
}
//實現接口的類
class LengthComparator implements Comparator<String>
{
	public int compare(String first,String second)
	{
		return first.length()-second.length();
	}
}

//比較時
Comparator<String> comp=new LengthComparator();
String[] words={"123","123124","2"};
Arrays.sort(words,comp);
  1. Cloneable接口
  • 在Java中對象之間的拷貝是淺拷貝,也就是將一個對象變量直接賦值給另一個變量,它們只是兩個引用指向了同一個對象。
  • 要實現深拷貝就必須調用clone方法,返回一個新的對象,在此新的對象上進行操作不會修改原對象。
  • Object對象實現了clone方法,但是是protected的。因此子類只能對自己類型的對象調用clone方法,而不能調用其它類型對象的clone方法。
  • Cloneable接口不包含任何方法,只是一個標記,將clone方法寫爲public的,表示可以調用父類的clone方法。
  • 如果要實現徹底的深拷貝,就要重寫clone方法,將類中的每一個引用所指的對象也進行拷貝。或者通過其他方法。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章