一、抽象類和抽象方法 在談論介面之前,我們先瞭解一下抽象類和抽象方法。我們知道,在繼承結構中,越往下繼承,類會變得越來越明確和具體,而往上回溯,越往上,類會變得越抽象和通用。我們有時候可能會需要這樣一個類,它只是表示了一個介面,但並沒有具體的實現,這就是一個抽象類。 抽象方法只有方法聲明而沒有方法體 ...
一、抽象類和抽象方法
在談論介面之前,我們先瞭解一下抽象類和抽象方法。我們知道,在繼承結構中,越往下繼承,類會變得越來越明確和具體,而往上回溯,越往上,類會變得越抽象和通用。我們有時候可能會需要這樣一個類,它只是表示了一個介面,但並沒有具體的實現,這就是一個抽象類。
抽象方法只有方法聲明而沒有方法體,也就是說用戶並不知道這個方法是如何實現的。抽象方法的聲明用到了 abstract 關鍵字,聲明方法如下:
abstract void f(); // 聲明一個抽象方法
包含抽象方法的類叫做抽象類。如果一個類包含一個或多個抽象方法,那麼該類必須被限定為抽象的。抽象類也用關鍵字abstract進行說明。
1)抽象類看起來和普通類相像,但是抽象類不能用new操作符創建它的實例;抽象類中抽象方法只有定義而沒有實現,它的實現由子類提供;
2)抽象類可以被繼承,但是其導出類必須為基類中所有的抽象方法提供方法定義,如果不這樣做,那麼導出類也將被強制限定為抽象類;
3)抽象類中可以沒有抽象方法,這樣的抽象類通常被用作基類型;
4)抽象類的構造方法定義為protected,這個構造方法在其子類的構造方法中被調用;
5)即使父類是具體的,其子類也可以是抽象的;
6)不能用new操作符創建一個抽象類的實例,但是抽象類可以用作一種數據類型被new調用。
下麵是一個簡單的抽象類的例子:
package com.tongye.abstraction; abstract class chouxiang{ abstract void f(); // 抽象方法 } class chouxiang1 extends chouxiang{ void f(){ System.out.println("抽象"); } } public class Abstraction { public static void main(String[] args){ chouxiang1 abstraction = new chouxiang1(); abstraction.f(); } }
二、介面
介面 interface 關鍵字使抽象的概念更向前邁了一步。abstract關鍵字允許人們在類中創建一個或多個沒有任何定義的方法,即提供了介面部分,但是沒有提供具體實現,其實現是由類的繼承者來創建的。 interface 關鍵字產生一個完全抽象的類,它根本沒有任何具體實現。
1)介面允許創建者確定方法名、參數列表和返回類型,但是沒有任何方法體;介面只提供了形式,而未提供任何具體實現;
2)要創建一個介面,需要用interface關鍵字來代替class關鍵字。可以在interface前面添加public關鍵字(僅限於該介面在與其同名的文件中被定義);如果不聲明,則它只包含包訪問許可權,只能在一個包內可用;
3)介面可以包含域,但這些域隱式地是 static 和 final 的;
4)可以用implements關鍵字來表明一個類實現了某個特定介面,即: class A implements B{} ;
下麵是一個簡單的應用介面的例子:
package com.tongye.interfaces; import java.util.Random; public interface StudentMessages { Random rand = new Random(47); int age = rand.nextInt(20); // 介面中的數據域 void studentName(); // 介面中的方法,只有方法名而沒有方法體 void studentAge(); void studentGrade(); } package com.tongye.interfaces; /* 類StudMessage1只實現了StudentMessages介面的部分方法,因而是抽象類 */ abstract class StudMessage1 implements StudentMessages { private String Stu_Name = "tongye"; private int Stu_Age = age; private char Stu_Grade; /* 這是介面中方法的實現 */ @Override public void studentName() { getName(); } @Override public void studentAge() { System.out.println(Stu_Age); } /* 這是新類自帶的方法 */ public void getName(){ System.out.println("my name is" + Stu_Name); } } /* StudMessage2繼承自StudMessage1,並實現了StudentMessages介面中的部分方法 */ class StudMessage2 extends StudMessage1{ @Override public void studentGrade() { System.out.println("1301"); } } public class Student { public static void main(String[] args){ StudMessage2 stud = new StudMessage2(); stud.studentName(); stud.studentAge(); stud.studentGrade(); } }
介面一個很重要的作用就是,可以實現類似C++中的多重繼承功能。我們知道,JAVA是不支持多重繼承的,但是通過使用介面,我們可以實現類似功能,用來表示“一個x是一個a和一個b以及一個c”。一個類可以繼承任意多個介面,這需要將所有的介面都置於implements關鍵字之後並用逗號隔開;可以將這個類向上轉型為每個介面,因為每一個介面都是一個獨立的類型。下麵這個程式演示了一下介面的這個功能:
/********/ package com.tongye.interfaces; public interface People { void isPeople(); } /********/ package com.tongye.interfaces; public interface Juniors { void isJuniors(); } /********/ package com.tongye.interfaces; public interface Chinese { void isChinese(); } /********/ package com.tongye.interfaces; class students implements People,Chinese,Juniors{ @Override public void isPeople(){ System.out.println("The student is a people"); } @Override public void isJuniors() { System.out.println("The student is a junior"); } @Override public void isChinese() { System.out.println("The student is a Chinese"); } } public class Student{ public static void people(People a){ // 介面作為一種數據類型傳遞給方法 a.isPeople(); } public static void junior(Juniors a){ a.isJuniors(); } public static void chinese(Chinese a){ a.isChinese(); } public static void main(String[] args){ students stud = new students(); people(stud); // stud被向上轉型為People類型 junior(stud); // stud被向上轉型為Juniors類型 chinese(stud); // stud被向上轉型為Chinese類型 } }
從這個程式中可以看出,類students既是People又是Juniors又是Chinese,在main方法中調用方法people、junior、chinese時,stud分別被向上轉型為People、Juniors和Chinese,這大大提升了代碼的靈活性。