1. 程式人生 > >12.類、抽象類、匿名類、內部類、繼承、介面、泛型

12.類、抽象類、匿名類、內部類、繼承、介面、泛型

類、抽象類、匿名類、內部類、繼承、介面、泛型

1.獲得一個類的類物件有哪些方式
2.過載(Overload)和重寫(Override)的區別。過載的方法能否根據返回型別進行區分?
3.說出幾條 Java 中方法過載的最佳實踐
4.抽象類和介面的區別
5.抽象類中是否可以有靜態的main方法
6.抽象類是否可實現(implements)介面
7.抽象類是否可繼承具體類(concrete class)
8.匿名內部類是否可以繼承其它類?是否可以實現介面
9.內部類分為幾種
10.內部類可以引用它的包含類(外部類)的成員嗎
11.請說一下 Java 中為什麼要引入內部類?還有匿名內部類
12.繼承(Inheritance)與聚合(Aggregation)的區別在哪裡
13.繼承和組合之間有什麼不同
14.為什麼類只能單繼承,介面可以多繼承
15.存在兩個類,B 繼承 A,C 繼承 B,能將 B 轉換為 C 麼?如 C = (C) B
16.如果類 a 繼承類 b,實現介面c,而類 b 和介面 c 中定義了同名變數,請問會出現什麼問題
17.介面是什麼
18.介面是否可繼承介面
19.為什麼要使用介面而不是直接使用具體類?介面有什麼優點
20.泛型的存在是用來解決什麼問題


1.獲得一個類的類物件有哪些方式
- 方法1:型別.class,例如:String.class
- 方法2:物件.getClass(),例如:"hello".getClass()
- 方法3:Class.forName(),例如:Class.forName("java.lang.String")
2.過載(Overload)和重寫(Override)的區別。過載的方法能否根據返回型別進行區分?
方法的過載和重寫都是實現多型的方式,區別在於前者實現的是編譯時的多型性,而後者實現的是執行時的多型性。過載發生在一個類中,同名的方法如果有不同的引數列表(引數型別不同、引數個數不同或者二者都不同)則視為過載;重寫發生在子類與父類之間,重寫要求子類被重寫方法與父類被重寫方法有相同的返回型別,比父類被重寫方法更好訪問,不能比父類被重寫方法宣告更多的異常(里氏代換原則)。過載對返回型別沒有特殊的要求。
不能
,因為呼叫時不能指定型別資訊,編譯器不知道你要呼叫哪個函式。
3.說出幾條 Java 中方法過載的最佳實踐
下面有幾條可以遵循的方法過載的最佳實踐來避免造成自動裝箱的混亂。
a)不要過載這樣的方法:一個方法接收 int 引數,而另個方法接收 Integer 引數。
b)不要過載引數數量一致,而只是引數順序不同的方法。
c)如果過載的方法引數個數多於 5 個,採用可變引數。
4.抽象類和介面的區別
引數抽象類介面
預設的方法實現它可以有預設的方法實現介面完全是抽象的。它根本不存在方法的實現
實現子類使用extends關鍵字來繼承抽象類。如果子類不是抽象類的話,它需要提供抽象類中所有宣告的方法的實現。子類使用關鍵字implements
來實現介面。它需要提供介面中所有宣告的方法的實現
構造器抽象類可以有構造器介面不能有構造器
與正常Java類的區別除了你不能例項化抽象類之外,它和普通Java類沒有任何區別介面是完全不同的型別
訪問修飾符抽象方法可以有publicprotecteddefault這些修飾符介面方法預設修飾符是public。你不可以使用其它修飾符。
main方法抽象方法可以有main方法並且我們可以執行它介面沒有main方法,因此我們不能執行它。
多繼承抽象方法可以繼承一個類和實現多個介面介面只可以繼承一個或多個其它介面
速度它比介面速度要快介面是稍微有點慢的,因為它需要時間去尋找在類中實現的方法。
新增新方法如果你往抽象類中新增新的方法,你可以給它提供預設的實現。因此你不需要改變你現在的程式碼。如果你往介面中新增方法,那麼你必須改變實現該介面的類。
5.抽象類中是否可以有靜態的main方法
抽象類中可以有靜態的main方法,main方法都是
6.抽象類是否可實現(implements)介面
介面可以繼承介面。抽象類可以實現(implements)介面,抽象類可繼承實體類,但前提是實體類必須有明確的建構函式。
7.抽象類是否可繼承具體類(concrete class)
介面可以繼承接口。抽象類可以實現(implements)介面,抽象類可繼承實體類,但前提是實體類必須有明確的建構函式
8.匿名內部類是否可以繼承其它類?是否可以實現介面
匿名的內部類不能extends(繼承)其它類,但一個內部類可以作為一個介面,由另一個內部類實現。
可以實現介面
9.內部類分為幾種        參考連結
Java內部類分4中:成員內部類、區域性內部類、靜態內部類、匿名內部類。
1、成員內部類:即作為外部類的一個成員存在,與外部類的屬性、方法並列。
2、區域性內部類:即在方法中定義的內部類,與區域性變數類似,在區域性內部類前不加修飾符public或private,其範圍為定義它的程式碼塊。
3、靜態內部類:靜態內部類定義在類中,任何方法外,用static定義。
4、匿名內部類 :匿名內部類是一種特殊的區域性內部類,建立時不需要指定類的名字,但是該類必須要要繼承抽象類或者是實現介面。
10.內部類可以引用它的包含類(外部類)的成員嗎
一個內部類物件可以訪問建立它的外部類物件的成員,包括私有成員。
11.請說一下 Java 中為什麼要引入內部類?還有匿名內部類        參考連結
完善多重繼承、實現事件驅動系統、閉包。
匿名內部類也就是沒有名字的內部類,正因為沒有名字,所以匿名內部類只能使用一次,它通常用來簡化程式碼編寫
12.繼承(Inheritance)與聚合(Aggregation)的區別在哪裡
繼承是編譯期邦定,聚合和執行期邦定,之所以鼓勵聚合不鼓勵繼承是因為聚合的晚繫結特性,讓程式能在執行期改變聚合類變為有可能
13.繼承和組合之間有什麼不同
1)組合(has-a)關係可以顯式地獲得被包含類(繼承中稱為父類)的物件,而繼承(is-a)則是隱式地獲得父類的物件,被包含類和父類對應,而組合外部類和子類對應。
2)組合關係在執行期決定,而繼承關係在編譯期就已經決定了。
3)組合是在組合類和被包含類之間的一種鬆耦合關係,而繼承則是父類和子類之間的一種緊耦合關係。
4)當選擇使用組合關係時,在組合類中包含了外部類的物件,組合類可以呼叫外部類必須的方法,而使用繼承關係時,父類的所有方法和變數都被子類無條件繼承,子類不能選擇。
5)最重要的一點,使用繼承關係時,可以實現型別的回溯,即用父類變數引用子類物件,這樣便可以實現多型,而組合沒有這個特性。
6)還有一點需要注意,如果你確定複用另外一個類的方法永遠不需要改變時,應該使用組合,因為組合只是簡單地複用被包含類的介面,而繼承除了複用父類的介面外,它甚至還可以覆蓋這些介面,修改父類介面的預設實現,這個特性是組合所不具有的。
7)從邏輯上看,組合最主要地體現的是一種整體和部分的思想,例如在電腦類是由記憶體類,CPU類,硬碟類等等組成的,而繼承則體現的是一種可以回溯的父子關係,子類也是父類的一個物件。
8)這兩者的區別主要體現在類的抽象階段,在分析類之間的關係時就應該確定是採用組合還是採用繼承。
9)引用網友的一句很經典的話應該更能讓大家分清繼承和組合的區別:組合可以被說成“我請了個老頭在我家裡幹活” ,繼承則是“我父親在家裡幫我幹活"。
14.為什麼類只能單繼承,介面可以多繼承        參考連結
如果存在多繼承,那個兩個父類有兩個一模一樣的方法怎麼辦,子類應該繼承哪一個方法。你也許會問如果多個介面中有相同的方法怎麼辦:介面中的方法都是方法名,沒有函式體,具體的實現需要靠實現類去實現,一旦實現類實現了方法,那麼就不存在多個介面有相同的方法名的出現的問題了,因為函式體都是一樣的。
15.存在兩個類,B 繼承 A,C 繼承 B,能將 B 轉換為 C 麼?如 C = (C) B

不能,參考里氏替換原則

16.如果類 a 繼承類 b,實現介面c,而類 b 和介面 c 中定義了同名變數,請問會出現什麼問題

在編譯時會發生錯誤(錯誤描述不同的JVM有不同的資訊,意思就是未明確的x呼叫,兩個x都匹配(就象在同時import java.util和java.sql兩個包時直接宣告Date一樣

17.介面是什麼

Java介面是一系列方法的宣告,是一些方法特徵的集合,一個介面只有方法的特徵沒有方法的實現,因此這些方法可以在不同的地方被不同的類實現,而這些實現可以具有不同的行為(功能)。 兩種含義:一,Java介面,Java語言中存在的結構,有特定的語法和結構;二,一個類所具有的方法的特徵集合,是一種邏輯上的抽象。

18.介面是否可繼承介面

介面可以繼承介面..但是要使用extends~而不是用implements

19.為什麼要使用介面而不是直接使用具體類?介面有什麼優點

實現多型……同一個介面,卻可以呼叫不同的底層實現。介面是定義行為,抽象類是實現公共行為的,具體類是實現具體行為的
使用介面其實就有點像實現虛擬函式的呼叫一樣, 用繼承介面的子類例項化聲名得介面就可以經過介面呼叫子類外部介面定義的函式。使用這種介面方式程式設計, 如果業務邏輯發生變化需求新增類多辦法, 就可以再不改動原來已經寫好的程式碼基礎上新增一個類來實現介面中定義的函式來實現!

20.泛型的存在是用來解決什麼問題    參考連結

泛型的引入可以解決之前的集合類框架在使用過程中通常會出現的執行時刻型別錯誤,因為編譯器可以在編譯時刻就發現很多明顯的錯誤。
引入泛型之前,要想實現一個通用的、可以處理不同型別的方法,你需要使用 Object 作為屬性和方法引數
Object缺點:
每次使用時都需要強制轉換成想要的型別
在編譯時編譯器並不知道型別轉換是否正常,執行時才知道,不安全
泛型的主要目的就是為了建立容器類
泛型的好處:
編譯時的強型別檢查
消除顯示的型別強制轉換
更好的程式碼複用性,比如實現泛型演算法