抽象類
《JAVA編程思想》一書中,將抽象類定義爲“包含抽象方法的類”。只要用abstract修飾的類就是抽象類,抽象類不一定包含抽象方法,但有抽象方法的類一定是抽象類。抽象方法是用abstract關鍵字修飾的方法,不用實現方法細節,由繼承了它的子類去實現。
[public] abstract class ClassName {
abstract void fun();
}
抽象類注意三點:
- 抽象方法必須爲public或protected,因爲private無法被子類繼承,就無法實現該方法,默認爲public.
- 抽象類不能創建對象.
- 如果子類繼承的父類是抽象類,而沒有實現它的抽象方法,那麼子類也必須修飾爲abstract.
接口
接口(interface)在軟件工程泛指供別人調用的方法或函數。在Java中,接口是一種行爲的抽象,比抽象類更加抽象的極度抽象類型,接口中定義的變量都會被修飾爲public static final
,而且必須賦初值,因此接口中只有常量;接口中的方法只能是public abstract
修飾的,其它的會報錯。
[public] interface InterfaceName {
public static final String s = "hello";
public abstract void fun();
}
接口注意兩點:
- 接口用於描述系統對外提供的所有服務,因此接口中的成員常量和方法都必須是公開(public)類型的,確保外部使用者能訪問它們
- 接口不涉及和任何具體實例相關的細節,因此接口沒有構造方法,不能被實例化,沒有實例變量,只有靜態(static)變量,被final修飾後就變爲了常量。
接口與抽象類的區別
語法層面
- 抽象類可以提供成員方法的實現細節,而接口只有抽象方法
- 抽象類可以有各個類型的成員變量,而接口只有public static final型的
- 抽象類中可以有靜態和非靜態代碼塊,而接口不行
- 一個類只能繼承一個抽象類,可以實現多個接口
設計層面
抽象類是一種事物的抽象,而接口是一種行爲的抽象。簡單來說,抽象類爲繼承的子類提供了一個模板,子類根據實際需求實現不同的細節,就像Android開發中爲Activity綁定Fragment的過程,許多代碼都是不變的,只是實現不同的Fargment實例,這就可以創建一個抽象類,將創建實例的過程定義在抽象方法中,而其它的部分定義在普通方法中,大大減少了代碼量;接口相當於定義了一個行爲,比如Fly,Bird類可以實現這個接口,擁有飛的行爲,而Dog類則不行。繼承關係強調“是不是”,而接口強調“有沒有”。
接口的寫法
接口不能實例化,也就是直接new出來,但我們常會看到這兩種寫法
List<String> list = new ArrayList<>();
public Runnable r = new Runnable()
{
@Override
public void run()
{
//Details
}
}
前一種是Java的多態,list可以指向實現它的接口的類;後一種是匿名內部類的寫法,詳解見Java--匿名內部類