1. 程式人生 > >簡述Java中抽象類和介面,及其兩者區別

簡述Java中抽象類和介面,及其兩者區別

在說區別之前,先簡要說一下什麼是抽象類和介面  

  1.抽象類

     用abstract修飾的類叫做抽象類。    

在講抽象類之前有必要強調一下abstract修飾符:

     1.abstract修飾的類為抽象類,此類不能有物件,(無法對此類進行例項化,說白了就是不能new);

     2.abstract修飾的方法為抽象方法,此方法不能有方法體(就是什麼內容不能有);



關於抽象類的使用特點:

    1.抽象類不能有物件,(不能用new此關鍵字來建立抽象類的物件);

    2.有抽象方法的類一定是抽象類,但是抽象類中不一定有抽象方法;

    3.抽象類中的抽象方法必須在子類中被重寫。

細心地同學可能會問到:抽象類不能被“new”,抽象方法必須重寫,那麼定義它們做什麼嘞?

       答:抽象類生來就註定它是要被繼承的,如果沒有任何一個類去繼承它的話,那麼也就失去了它的意義;抽象方法生來就是要被重寫的,而且是必須重寫。(只要繼承了某個抽象類,就必須去重寫此抽象類中含有的抽象方法)

話不多說,看程式碼:

public abstract class Animal {
 public abstract void eat();
 public abstract void sleep();
}

以上程式碼是定義了一個叫做animal的抽象類,其中含有eat()和sleep()兩個抽象方法。


這裡指的注意的是:抽象方法不能有方法體,在方法後面加一個大括號而裡面什麼都不寫也是不行的,編譯器會報“abstract methods do not specify a body”這樣一個錯誤。如下:

定義了一個animal類之後再定義一個cat類:

public class Cat extends Animal{

	@Override
	public void eat() {
		System.out.println("我是貓,我吃的是貓糧呀");
		
	}

	@Override
	public void sleep() {
		System.out.println("我是貓,我比你們人類睡的時間短!");
		
	}
	
}

在這裡指的注意的是:當一個類繼承抽象類的時候,這個類必須去重寫所繼承的抽象類的抽象方法,否則編譯器會報“The type Cat must implement the inherited abstract method Animal.eat()”的錯誤。具體如下:

而,當重寫完相對應的抽象類中的所有抽象方法之後,編譯器也就不再報錯:

此時,我再來寫一個Person類:

public class Person extends Animal {

	@Override
	public void eat() {
		// TODO Auto-generated method stub
		System.out.println("我是人,我要吃大魚大肉!!!");
	}

	@Override
	public void sleep() {
		// TODO Auto-generated method stub
		System.out.println("我是人,每天必須睡夠24個小時!!!!");
	}
}

OK,現在類已經寫完了。接下來結合以上的程式碼說一下抽象類的用處:

       細心地同學可以看得出,在cat和person這兩個類中都含有了sleep和eat這兩個方法,但是它們的方法體卻不一樣。重點就在這裡,假設不定義animal這個抽象類以用來讓cat和person去繼承的話,雖然也要在cat和person中定義sleep和eat這兩個方法,看似程式碼上沒有太多簡化。但是這背後卻隱藏著一個規範問題:也就是“是不是”的問題。cat和person都“是”animal,所以就必須繼承animal裡面的方法。相當於提供了一個大的體制。就好比人:人活著就必須要遵守國家的法律,而至於你信仰佛,還要遵守“佛法”,你信仰共產黨,你還要遵守黨章和黨紀。那就是你自己的事情了

2.介面

     介面就是一個規範和抽象類比較相似。它只管做什麼,不管怎麼做。通俗的講,藉口就是某個事物對外提供的一些功能的宣告,其定義和類比較相似,只不過是通過interface關鍵字來完成

其中重要的幾個知識點:

   1.介面中的所有屬性預設為:public static final ****;

   2.介面中的所有方法預設為:public abstract ****;

   3.介面不再像類一樣用關鍵字 extends去“繼承”,而是用 implements 去“實現”,也就是說類和介面的關係叫做實現,(例如:A類實現了B介面,那麼成為A為B介面的實現類。而類與類之間的繼承的話,叫做A類繼承了B類,其中B類即為A類的父類)。實現介面與類的繼承比較相似

程式設計一事書讀的再多沒用,只會培養出來嘴上懂得怪多,但是屁都敲不出來的鳥人!!動手出真知!!!微笑具體看一下程式碼:

public interface Sleep {
	public static int a = 1;
	public static int b = 2;
	public void ioSleep(int i);

}
public interface Eat {
	public abstract void ioEat();
}
public interface Study {
	public void ioStudy();
}
public class Cat implements Sleep,Eat{

	@Override
	public void ioSleep(int i) {
		System.out.println("我是貓,我每天都不用睡覺!!!");
	}

	@Override
	public void ioEat() {
		System.out.println("我是貓,我吃貓糧!!!");
	}
}
public class Person implements Sleep,Eat,Study{

	@Override
	public void ioStudy() {
		System.out.println("我是人,我每天都要學習");
	}

	@Override
	public void ioEat() {
		System.out.println("我是人,我要吃大魚大肉還要喝酒");
	}

	@Override
	public void ioSleep(int i) {
		System.out.println("我是人,我每天要睡24小時");
	}
}

以上程式碼定義了三個介面分別是:Study,Eat,Sleep,以及兩個類分別是Cat和Person。其中Cat類實現了兩個介面分別是:Eat和Sleep,而Person實現了三個介面分別是:Study,Eat,Sleep。這是為什麼呢?就是因為Cat並不需要學習,而Person需要學習,所以在Cat類中沒有實現Study這個介面,而在Person中卻是有的。那麼顯而易見,介面所闡述的是“有沒有”的問題,而剛剛所說的抽象類闡述的是“是不是”的問題

所以也就可以列出抽象類和介面的幾點區別

      1.抽象類描述的是“是不是”的問題,而介面描述的是“有沒有”的問題;

      2.在Java中類的繼承是“單繼承”,可以“多對一”,但是不允許“一對多”。而一個類卻可以同時實現多個介面;

關於介面的注意事項:

如果把Cat的程式碼裡面加上“a++"這樣一句程式碼的話,編譯器會報“The final field Sleep.a cannot be assigned”這樣一個錯誤。至於原因就是因為在介面中所有的屬性的修飾符都預設為"public static final",(雖然當時定義a的時候並沒有明確指出要用final修飾)而final所修飾的屬性裡面的常量值是不能做修改的。

以上程式碼報“Abstract methods do not specify a body”的錯誤,因為介面中的方法預設修飾符為“public abstract”