面向对象回顾(异常(try、catch、throw、throws和finally)、接口和抽象类、面向对象特征、泛型(extends/super))
1. 異常
1.1 JAVA語言如何進行異常處理
Java 通過面向對象的方法進行異常處理,把各種不同的異常進行分類,并提供了良好的接口。
在Java中,每個異常都是一個對象,它是Throwable類或其它子類的實例。
當一個方法出現異常后便拋出一個異常對象,該對象中包含有異常信息,調用這個對象的方法可以捕獲到這個異常并進行處理。
1.2 關鍵字:throws,throw,try,catch,finally分別代表什么意義?在try塊中可以拋出異常嗎?
Java的異常處理是通過5個關鍵詞來實現的:try、catch、throw、throws和finally。
一般情況下是用try來執行一段程序,如果出現異常,系統會拋出(throws)一個異常,這時候你可以通過它的類型來捕捉(catch)它,或最后(finally)由缺省處理器來處理。
用try來指定一塊預防所有”異常”的程序。
緊跟在try程序后面,應包含一個catch子句來指定你想要捕捉的”異常”的類型。
throw語句用來明確地拋出一個”異常”。
throws用來標明一個成員函數可能拋出的各種”異常”。
Finally為確保一段代碼不管發生什么”異常”都被執行一段代碼。
可以在一個成員函數調用的外面寫一個try語句,在這個成員函數內部寫另一個try語句保護其他代碼。
每當遇到一個try語句,”異常“的框架就放到堆棧上面,直到所有的try語句都完成。
如果下一級的try語句沒有對某種”異常”進行處理,堆棧就會展開,直到遇到有處理這種”異常”的try語句。
2.?Java的接口和C++的虛類的相同和不同處
由于Java不支持多繼承,而有可能某個類或對象要使用分別在幾個類或對象里面的方法或屬性,現有的單繼承機制就不能滿足要求。
與繼承相比,接口有更高的靈活性,因為接口中沒有任何實現代碼。
當一個類實現了接口以后,該類要實現接口里面所有的方法和屬性,并且接口里面的屬性在默認狀態下面都是public static,所有方法默認情況下是public。
一個類可以實現多個接口。
3.?abstract class和interface有什么區別?
3.1 抽象類
聲明方法的存在而不去實現它的類被叫做抽象類(abstract class),它用于要創建一個體現某些基本行為的類,并為該類聲明方法,但不能在該類中實現該類的情況。
不能創建abstract 類的實例。
然而可以創建一個變量,其類型是一個抽象類,并讓它指向具體子類的一個實例。
不能有抽象構造函數或抽象靜態方法。
Abstract 類的子類為它們父類中的所有抽象方法提供實現,否則它們也是抽象類為。
取而代之,在子類中實現該方法。知道其行為的其它類可以在類中實現這些方法。
3.2 接口(interface)
是抽象類的變體。
在接口中,所有方法都是抽象的。
多繼承性可通過實現這樣的接口而獲得。
接口中的所有方法都是抽象的,沒有一個有程序體。
接口只可以定義static final成員變量。
接口的實現與子類相似,除了該實現類不能從接口定義中繼承行為。當類實現特殊接口時,它定義(即將程序體給予)所有這種接口的方法。然后,它可以在實現了該接口的類的任何對象上調用接口的方法。
由于有抽象類,它允許使用接口名作為引用變量的類型。通常的動態聯編將生效。引用可以轉換到接口類型或從接口類型轉換,instanceof 運算符可以用來決定某對象的類是否實現了接口。
3.3 區別
- 接口中所有的方法隱含的都是抽象的。而抽象類則可以同時包含抽象和非抽象的方法。
- 類可以實現很多個接口,但是只能繼承一個抽象類
- 類可以不實現抽象類和接口聲明的所有方法,當然,在這種情況下,類也必須得聲明成是抽象的。
- 抽象類可以在不提供接口方法實現的情況下實現接口。
- Java接口中聲明的變量默認都是final的。抽象類可以包含非final的變量。
- Java接口中的成員函數默認是public的。抽象類的成員函數可以是private,protected或者是public。
- 接口是絕對抽象的,不可以被實例化。抽象類也不可以被實例化,但是,如果它包含main方法的話是可以被調用的。
4.面向對象的特征有哪些方面
4.1 抽象
抽象就是忽略一個主題中與當前目標無關的那些方面,以便更充分地注意與當前目標有關的方面。
抽象并不打算了解全部問題,而只是選擇其中的一部分,暫時不用部分細節。
抽象包括兩個方面,一是過程抽象,二是數據抽象。
4.2 繼承
繼承是一種聯結類的層次模型,并且允許和鼓勵類的重用,它提供了一種明確表述共性的方法。
對象的一個新類可以從現有的類中派生,這個過程稱為類繼承。
- 新類繼承了原始類的特性,新類稱為原始類的派生類(子類),而原始類稱為新類的基類(父類)。
- 派生類可以從它的基類那里繼承方法和實例變量,并且類可以修改或增加新的方法使之更適合特殊的需要。
4.3 封裝
封裝是把過程和數據包圍起來,對數據的訪問只能通過已定義的界面。
面向對象計算始于這個基本概念,即現實世界可以被描繪成一系列完全自治、封裝的對象,這些對象通過一個受保護的接口訪問其他對象。
4.4 多態性
多態性是指允許不同類的對象對同一消息作出響應。
多態性包括參數化多態性和包含多態性。
多態性語言具有靈活、抽象、行為共享、代碼共享的優勢,很好的解決了應用程序函數同名問題。
5.Comparable和Comparator接口的作用以及它們的區別
Java提供了只包含一個compareTo()方法的Comparable接口。
- 這個方法可以個給兩個對象排序。
- 具體來說,它返回負數,0,正數來表明輸入對象小于,等于,大于已經存在的對象。
Java提供了包含compare()和equals()兩個方法的Comparator接口。
- compare()方法用來給兩個輸入參數排序,返回負數,0,正數表明第一個參數是小于,等于,大于第二個參數。
- equals()方法需要一個對象作為參數,它用來決定輸入參數是否和comparator相等。
- 只有當輸入參數也是一個comparator并且輸入參數和當前comparator的排序結果是相同的時候,這個方法才返回true。
6.?泛型
6.1 介紹
泛型,即“參數化類型”。
一提到參數,最熟悉的就是定義方法時有形參,然后調用此方法時傳遞實參。
那么參數化類型怎么理解呢?顧名思義,就是將類型由原來的具體的類型參數化,類似于方法中的變量參數,此時類型也定義成參數形式(可以稱之為類型形參),然后在使用/調用時傳入具體的類型(類型實參)。
public class GenericTest {public static void main(String[] args) {/*List list = new ArrayList();list.add("qqyumidi");list.add("corn");list.add(100);*/List<String> list = new ArrayList<String>();list.add("qqyumidi");list.add("corn");//list.add(100); // 1 提示編譯錯誤for (int i = 0; i < list.size(); i++) {String name = list.get(i); // 2System.out.println("name:" + name);}}}采用泛型寫法后,在//1處想加入一個Integer類型的對象時會出現編譯錯誤,通過List<String>,直接限定了list集合中只能含有String類型的元素,從而在//2處無須進行強制類型轉換,因為此時,集合能夠記住元素的類型信息,編譯器已經能夠確認它是String類型了。
6.2?解釋一下extends 和super 泛型限定符
6.2.1?泛型中上界和下界的定義
上界<? extend Fruit>
下界<? super Apple>
6.2.2?上界和下界的特點
上界的list只能get,不能add(確切地說不能add出除null之外的對象,包括Object)
下界的list只能add,不能get
6.2.3 示例代碼
import java.util.ArrayList; import java.util.List;class Fruit {} class Apple extends Fruit {} class Jonathan extends Apple {} class Orange extends Fruit {}public class CovariantArrays {public static void main(String[] args) {//上界List<? extends Fruit> flistTop = new ArrayList<Apple>();flistTop.add(null);//add Fruit對象會報錯//flist.add(new Fruit());Fruit fruit1 = flistTop.get(0);//下界List<? super Apple> flistBottem = new ArrayList<Apple>();flistBottem.add(new Apple());flistBottem.add(new Jonathan());//get Apple對象會報錯//Apple apple = flistBottem.get(0);} }上界<? extend Fruit> ,表示所有繼承Fruit的子類,但是具體是哪個子類,無法確定,所以調用add的時候,要add什么類型,誰也不知道。但是get的時候,不管是什么子類,不管追溯多少輩,肯定有個父類是Fruit,所以,我都可以用最大的父類Fruit接著,也就是把所有的子類向上轉型為Fruit。
下界<? super Apple>,表示Apple的所有父類,包括Fruit,一直可以追溯到老祖宗Object 。那么當我add的時候,我不能add Apple的父類,因為不能確定List里面存放的到底是哪個父類。但是我可以add Apple及其子類。因為不管我的子類是什么類型,它都可以向上轉型為Apple及其所有的父類甚至轉型為Object 。但是當我get的時候,Apple的父類這么多,我用什么接著呢,除了Object,其他的都接不住。
所以,歸根結底可以用一句話表示,那就是編譯器可以支持向上轉型,但不支持向下轉型。具體來講,我可以把Apple對象賦值給Fruit的引用,但是如果把Fruit對象賦值給Apple的引用就必須得用cast。
總結
以上是生活随笔為你收集整理的面向对象回顾(异常(try、catch、throw、throws和finally)、接口和抽象类、面向对象特征、泛型(extends/super))的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 面向对象回顾(构造函数、覆盖和重载、Qu
- 下一篇: 面向对象回顾(静态变量、类加载机制/双亲