1. 程式人生 > >JAVA的abstract修飾符 && 介面interface用法 && 抽象類和interface的差別

JAVA的abstract修飾符 && 介面interface用法 && 抽象類和interface的差別

abstract修飾符可以修飾類和方法。

(1)abstract修飾類,會使這個類成為一個抽象類,這個類將不能生成物件例項,但可以做為物件變數宣告的型別(見後面例項),也就是編譯時型別。抽象類就相當於一類的半成品,需要子類繼承並覆蓋其中的抽象方法。

(2)abstract修飾方法,會使這個方法變成抽象方法,也就是隻有宣告而沒有實現,需要子類繼承實現(覆蓋)。

(3)注意的地方:

       A:有抽象方法的類一定是抽象類。但是抽象類中不一定都是抽象方法,也可以全是具體方法。abstract修飾符在修飾類時必須放在類名前。abstract修飾方法就是要求其子類覆蓋(實現)這個方法,呼叫時就可以以多型方式呼叫子類覆蓋(實現)後的方法,除非子類本身也是抽象類。

       B:父類是抽象類,其中有抽象方法,那麼子類繼承父類,並把父類中的所有抽象方法都實現(覆蓋)了,子類才有建立物件的例項的能力,否則子類也必須是抽象類。簡單的例子下面有一個抽象類

abstract class E{
	public abstract void show();
}

class F extends E{
	public void show(){
		System.out.print("test all");
	}
}
public class TestNew 
{

	public static void main(String[] args)throws InterruptedException {
		// TODO Auto-generated method stub
		E e = new F();
		e.show();
	}
}

在主方法裡面定義一個父類引用指向子類物件,就會發生多型現象。執行結果就是在console輸出test all。
===================================================================================================================

       extends是繼承父類,只要那個類不是宣告為final就能繼承。JAVA中不支援多重繼承,但是可以用介面來實現,這樣就要用到implements。繼承只能繼承一個類,但implements可以實現多個介面,用逗號分開就行了,比如 class A extends B implements C,D,E。
       與extends的差別:extends 是繼承某個類,繼承之後可以使用父類的方法也可以重寫父類的方法;implements 是實現多個介面,介面的方法必須重寫才能使用。要注意以下幾點:

A,介面中一般定義的是常量和抽象方法。抽象類中可以包含抽象方法,也可以有非抽象方法,但是有抽象方法的類一定是抽象類。抽象方法不能有方法體。

B,介面(interface)中,方法只能定義抽象方法而且預設是Public,常量則是public static final 修飾的(不管有沒有這些修飾符,方法和常量預設具這種屬性)。

C,一個類可以實現多個無關的介面(這點和繼承要有所區別)。

D,介面可以繼承其他的介面,並新增新的屬性和抽象方法。

E,在類中實現介面的方法時必須加上public修飾符。

       示例:

interface Runner{	//定義介面
	int i = 3;
	void start();
	void run();
	void stop();
}

interface Eater extends Runner{		//介面間可以繼承,並新增新的屬性方法
	public final static int j = 4;	//常量的修飾
	void openMonth();
	void upAndDown();
	void goIn();
}

class TT implements Eater{		
	public void start(){			//實現介面的同時會繼承介面的變數,實現介面的方法加上public
		System.out.println("----start()----");
	}
	public void run(){
		System.out.println("----run()----");
	}
	public void stop(){
		System.out.println("----stop()----");
	}
	public void openMonth(){
		System.out.println("----openMonth()----");
	}
	public void upAndDown(){
		System.out.println("----upAndDown()----");
	}
	public void goIn(){
		System.out.println("----goIn()----");
	}
}

public class TestNew {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Runner tt = new TT();	  				//實現物件指向介面引用的父類
		System.out.println(TT.i);				//類名.靜態變數
		System.out.println(Runner.i);		//介面名.靜態變數
		tt.start();
		
		Eater ee = new TT();						//實現物件指向介面引用
		System.out.println(ee.j);				//介面引用.靜態變數
		System.out.println(Eater.j);		//介面名.靜態變數
		ee.start();
	}
}

執行結果:
3
3
----start()----
4
4
----start()---- 

得到這個結果,需要注意的幾點:(1)靜態變數(相當於常量)可以用類名.靜態變數名直接使用,介面又是類的一種,所以介面名.靜態變數名可用;(2)介面引用.靜態變數是多型的體現。

======================================================================================================
這裡需要談到抽象類和Interface的差別,abstract class和interface是支援抽象類定義的兩種機制。正是由於這兩種機制的存在,才賦予了Java強大的面向物件能力,兩者的區別如下:


(1)相同點
A,兩者都是抽象類,都不能例項化。
B,interface實現類及abstrct class的子類都必須要實現已經宣告的抽象方法。

(2)不同點
A,interface實現,要用implements,而abstract class的實現,要用extends。
B,一個類可以實現多個interface,但一個類只能繼承一個abstract class。
C,interface強調特定功能的實現,而abstract class強調所屬關係。
D,儘管interface實現類及abstrct class的子類都必須要實現相應的抽象方法,但實現的形式不同。interface中的每一個方法都是抽象方法,都只是宣告的(declaration, 沒有方法體),必須要實現。而abstract class的子類可以有選擇地實現。
       抽象類的這個選擇有兩點含義:一是Abastract class中並非所有的方法都是抽象的,只有那些冠有abstract的方法才是抽象的,子類必須實現。那些沒有abstract的方法,在Abstrct class中必須定義方法體。二是abstract class的子類在繼承它時,對非抽象方法既可以直接繼承,也可以覆蓋;而對抽象方法,可以選擇實現,也可以通過再次宣告其方法為抽象的方式,無需實現,留給其子類來實現,但此類必須也宣告為抽象類。既是抽象類,當然也不能例項化。

E,interface是完全抽象的,只能宣告方法,而且只能宣告pulic的方法,不能宣告private及protected的方法,不能定義方法體,也不能宣告例項變數。


參考博文:http://blog.csdn.net/zhandoushi1982/article/details/8458081