1. 程式人生 > >Java中的抽象類、抽象方法、介面

Java中的抽象類、抽象方法、介面

抽象

更具Java的萬物皆物件的思想,將事物共有的屬性、功能抽取出來。Java中抽象的前提是繼承關係,沒有了繼承,抽象類就失去了靈魂。在繼承關係中,子類可以繼承父類的成員變數和成員方法,但是每個子類的方法的具體實現可能不一致,(可以通過重寫(方法覆蓋)父類的方法解決)但是這樣父類具體實現某個方法就失去了意義。這裡我們僅僅對父類中的方法加以宣告,不做方法的具體實現,子類中(必須)具體實現父類所有的“為實現的方法”。來更加符合面向物件的多型。抽象類向上抽取子類的特點,得到所有子類的共性功能,但不給出功能實現,強制子類根據自身差異性具體去重寫。

  • 抽象類、抽象方法的定義
	public abstract class <類名稱> {
		<成員變數定義>;
		public abstract <返回值> <方法名稱>();
	}

抽象方法需要用abstract關鍵字宣告。且當某個類中含有至少一個抽象方法時,該類必須用abstract宣告為抽象類。定義抽象類時不能有{},即使{}內沒有任何語句。抽象類中可以不含有抽象方法(抽象類中可以含有非抽象方法),但抽象方法必須被抽象類包含。
抽象類中可以含有構造方法。
抽象類不能直接例項化產生物件,要想例項化的前提是實現(方法重寫)抽象類中的所有抽象方法
繼承抽象類的子類必須先實現該抽象類的所有抽象方法才能例項化,否則,子類仍然是抽象類。
IDEA中通過快捷鍵Alt+Insert提示直接覆蓋抽象類的所有抽象方法。

介面

介面為了定義擴充套件功能。Java中繼承僅支援單繼承、支援多層繼承,但不支援多繼承,為了彌補無法多繼承,可以用介面來實現某個類實現多個介面,而提升Java程式功能。介面更加符合Java面向物件中封裝、多型的思想。(降低程式耦合度、提高程式碼複用)
介面的定義是定義擴充套件空間,那個類想要具備這個額外功能,就可以去實現這個介面,重寫介面的擴充套件功能。

  • 介面定義方式
	public interface <介面名稱>{
		public static fianl <成員變數>;
		public abstract <返回值> <方法名>(<方法引數列表>);
	}

介面不同於類,介面不能直接例項化建立物件。介面是以interface關鍵字定義的。介面中的成員變數預設用public static fina聯合修飾,==介面中成員變數的值不能被修改!==成員方法預設用public abstract修飾,介面中的方法必須都是抽象方法。介面可以繼承其他介面從而實現新增新的屬性和方法。Java中類不能多繼承,但介面可以多繼承。
然而實際上,Java提供了一種預設方法的方式可以讓介面型別中定義已實現的方法(非抽象方法)。
介面中不能有構造方法。
被final修飾的介面中的成員方法意味常量,所以用大寫字母命名。
被abstract修飾的方法不能用private修飾。(繼承發生矛盾)
被abstract修飾的方法不能用final修飾。(方法不能重寫而矛盾)
被abstract修飾的方法不能用static修飾(靜態方法不存在繼承、過載所以矛盾)

  • 介面中的預設方法
	public interface <介面名稱>{
		public static fianl <成員變數>;
		public <返回值> <方法名>(<方法引數列表>);
		public default <返回值> <方法名>(<方法引數列表>) {
			<預設方法方法體中語句>;
		}
	}

Java8中允許介面定義預設方法,預設方法必須使用default修飾,且不能用static和final修飾,預設也只能用public修飾。通過預設方法實現“多繼承”。不能直接使用介面中定義的預設方法,需要使用介面實現類來呼叫預設方法。

  • 介面實現類
	public class <類名稱> implements <介面名稱>{
		@Override
		public <返回值> <介面中抽象類名稱> (<引數列表>) {
			<實現介面的方法體中的語句>;
		}
	}

介面的實現類必須覆蓋介面中全部的抽象類和抽象方法,然後可以用該類名new例項化。這裡可以呼叫介面中的成員變數但不能修改(預設final修飾)。
介面中也可以實現父介面引用執行子類物件。(介面的多型形式

	public class <類名稱> {
		public static void main(String[] arg) {
			<介面名> <物件名> = new <介面實現類構造方法>();
		}
	}

該物件名可以引用出介面中最終的成員變數,也可以引用實現了介面中抽象方法的方法。若要訪問介面實現類中特有的方法(介面實現類中新定義的方法)時,需要向下型別轉換。即通過==((<介面實現類>) <物件名>).<介面實現類中新定義的方法>;==的方式呼叫。(多型形式)

  • instanceof(運算子)關鍵字
    <介面實現類的物件> instanceof <介面實現類>運算結果為true
    <介面引用指向介面實現類的物件> instanceof <介面型別>運算結果為true
    <介面引用指向介面實現類的物件> instanceof <介面實現類>運算結果為true
public class Demo {
    public static void main(String[] args) {
    	<介面實現類> <物件1> = new <介面實現類的構造方法>();
    	<介面型別> <物件2> = new <介面實現類的構造方法>();
    	System.out.println(<物件1> instanceof <介面實現類>);//true
    	System.out.println(<物件2> instanceof <介面>);//true
    	System.out.println(<物件2> instanceof <介面實現類>);//true    	
    }
}
  • 介面、類之間的關係

介面與介面之間可以實現多繼承!
類與類之間只能單繼承、多層繼承,但不能實現多繼承!
類與介面之間可以是繼承關係(此時是抽象類繼承了介面)、類與介面之間還可以是實現關係(此時類是介面實現類)。

  • 抽象類和介面的區別

抽象類中含有構造方法,介面中沒有構造方法
抽象類中既可以有抽象方法(也可以沒有)也可以有非抽象方法,而介面中只能有抽象方法
抽象類中成員變數可以用final或者不用final修飾,介面中所有的成員變數都是公共的靜態常量(介面中的成員變數只能用public static final聯合修飾)
抽象類和介面都不能直接例項化