JAVA基礎回顧(一)
1.面向物件和麵向過程的區別
面向過程:
優點:效能要高於面向物件,面向物件中的類在呼叫的時候需要例項化,中間需要載入的資源比較多(微控制器、嵌入式開發、linux一般使用面向過程的思想進行開發)
缺點:不易維護,不易複用,不易擴充套件
面向物件:
優點:易於維護,易於複用,易於擴充套件,因為封裝、繼承、多型等特性的存在,所以能夠設計出耦合度很低的系統,並使系統更加靈活
缺點:效能比面向物件低
2.JAVA語言的特點
1.面向物件(封裝、繼承、多型)
2.可靠安全
- 無指標運算(沒有指標的話,就不能隨便的去訪問不該訪問的記憶體)
- 陣列邊界檢查
- 強制型別轉換檢查
3.支援多執行緒還有網路程式設計
3.什麼是JAVA虛擬機器?什麼是位元組碼?
Java虛擬機器是在機器和程式之間加入了一層虛擬的機器。這層虛擬機器在任何平臺上都為程式提供了一層共同的介面,所以Java程式易移植。程式只需要面向虛擬機器,再由虛擬機器來面向機器工作。源程式經過編譯後生成虛擬機器能夠理解的位元組碼檔案,位元組碼檔案再由虛擬機器來解釋執行。虛擬機器將每一條要執行的位元組碼送給直譯器,直譯器將其翻譯成特定機器上的特定機器碼,然後再在特定的機器上執行
使用位元組碼的好處:使java程式可移植性很強
4.什麼是JAVA的主類
主類即包含main()方法的類,主類是java程式執行的入口點
5.JDK和JRE是什麼?
JDK即JAVA開發包(java development kit)
JRE即JAVA執行環境(java runtime environment)
JDK包含了JRE JDK還包括
- javac ------編譯器,將.java字尾的原始檔編譯成.class的位元組碼檔案
- java------執行工具,執行.class檔案
- jar------打包工具
- javadoc------文件生成器
- jdb debugger------除錯工具
普通使用者只需要安裝JRE來執行java程式,而開發者必須安裝JDK來進行開發
6.過載和重寫的區別
過載:發生在同一個類中,多個方法的方法名相同,但是引數型別不同,引數數量不同,引數順序不同,方法返回值和訪問修飾符可以不同,發生在編譯時
重寫:發生在具有繼承關係的兩個類中,一般是子類和父類。
1.引數列表要相同
2.返回型別要與被重寫的方法完全相同
3.丟擲的異常要小於等於父類
4.訪問修飾符要大於或等於父類的訪問修飾符
5.如果父類的方法為private或者final,則子類不能構成重寫
6.被宣告為static的方法不能被重寫,但是可以被再次宣告
7.構造方法不能被重寫
對父類方法進行重寫要注意“三同、一小、一大”
- 三同:返回值型別、方法名、形參列表相同
- 一小:丟擲的異常比父類宣告丟擲的異常要小
- 一大:子類的方法訪問修飾符要跟父類方法相等或者更大
7.封裝繼承和多型
封裝:
- 定義 隱藏物件的屬性和實現細節,對外只公開呼叫介面
- 目的 增強安全性
- 基本要求 把所有屬性私有化,對每個屬性提供get和set方法,如果有一個有參建構函式的話,一定要寫一個無參建構函式。有時還重寫toString()方法,但是不是必須的
繼承:
- 目的 實現程式碼的複用
- 子類不能繼承父類的構造方法和私有屬性
- 子類不能繼承父類的訪問控制符為private的方法
多型:
- 實現多型的三個條件 ---必須是繼承關係--- ---子類重寫了父類的方法--- ---父類的引用指向子類的物件(向上轉型)---
- 多型就是一個物件的多種形態,同樣的變數,呼叫同樣的方法,卻產生不同的行為例:Person是Man的父類,都有walk()方法,Person p1 = new Person(); p1.walk() 呼叫的是父類的方法, Person p2 = new Man(); p2.walk() 呼叫的是子類的方法 但是p2不能呼叫子類新增的方法work(),必須要向 下轉型才能呼叫子類新增的方法 Man p = (Man)p2; p.work()
-
(1)如果子類重寫了父類的某個方法,那麼呼叫的就是子類的方法
(2)如果子類沒有重寫父類的方法,那麼呼叫的就是父類的方法
(3)如果子類中增加了父類中沒有的新方法,那麼這個父類引用是不能呼叫子類中的這個新方法的,因為子類物件自動向上轉型成了父類物件
(4)如果子類與父類有同名的成員變數或者靜態變數,那麼子類自動向上轉型成父類物件,那麼輸出的必然是父類的變數
(5)如果PersonA AA = new PersonA(),那這就是一個實實在在的子類物件,那麼A.a就會覆蓋父類的同名變數,如果子類中沒有同名變數,那麼呼叫的就是父類的a,也就是說子類可以繼承父類的成員變數和靜態變數,同時也可以覆蓋父類的成員變數和靜態變數
8.介面和抽象類的區別
介面:
- 一個介面可以被多個類實現,一個類也可以實現多個介面
- 介面中的所有欄位都預設是static final,所以修飾符寫不寫都是一樣的,介面的所有方法都預設是抽象方法,預設修飾符為static abstract,寫不寫都是一樣的
- 介面沒有構造方法
不同點:
- 介面可以多實現,但是抽象類只能單繼承
- 抽象類中可以有非抽象的方法和構造方法、變數,但是介面只能有抽象方法和靜態常量,介面中不能有普通資料成員,必須是靜態的且不可改變的資料成員,要用static final來修飾
- 抽象類和子類具有父子關係,子類能擁有父類的一些屬性。介面雖然是由某一個類來實現,但是因為介面中的都是靜態常量,所以不構成繼承關係
相同點:
- 無論是介面還是抽象類,都不能直接例項化,而是需要依靠實現類或者子類來例項化
- 介面和抽象類都必須實現其中的所有方法
總結:
某種意義上來說介面是一種特殊的抽象類,如果你不需要刻意表達屬性上的繼承的話,你可以用介面來代替抽象類
9.equals()和 ==的比較
- 通俗的拿人舉個例子,==其實是看左邊的人和右邊的人是不是同一個人,而equals()是看左邊的人和右邊的人是不是長得相同,但是長相相同不一定是一個人
- 用術語說的話==判斷的是兩個變數或者例項指向的記憶體地址是否相同,而equals()比較的是兩個變數或者例項指向的記憶體地址中儲存的值是不是相同
- ==比較的是記憶體地址,equals()比較的是值
10.String和StringBuffer還有StringBuilder的區別
- 可變性
- String類中使用的字元陣列來儲存字串,private final char value[],所以String是不可變的
- StringBuffer和StringBuilder都是繼承自AbstractStringBuilder類,AbstractStringBuilder也是使用字元陣列來儲存字串char[]value,所以這兩種物件是可變的
- 執行緒安全
- 因為String是不可變得,相當於常量,所以是執行緒安全的(安全)
- StringBuffer對方法加了同步鎖或者對呼叫的方法加了同步鎖,所以是執行緒安全的(安全)
- StringBuilder沒有加同步鎖,所以是非執行緒安全的(不安全)
- 效能
- 每次對String進行改變的時候,都會生成一個新的String物件,然後將引用指向新的String物件
- 每次對StringBuffer進行改變的時候,都是相當於在原物件中對內容進行append()追加,並不生成新的物件,也不改變引用
- StringBuilder在相同情況下相對StringBuffer能提升10%-15%的效能,但是要冒執行緒不安全的危險(效能提升是因為沒加同步鎖)
- 使用情況總結
- 操作少量資料的情況下---使用String---
- 單執行緒下字元緩衝區下操作大量資料---使用StringBuilder---
- 多執行緒下字元緩衝區下操作大量資料---使用StringBuffer---
11.為什麼在一個靜態方法內部呼叫一個非靜態成員是非法的?
因為靜態方法可以通過---類名.靜態方法名---來呼叫的,可以不建立物件,所以在靜態方法中不能呼叫非靜態的變數,也不能訪問非靜態的成員
12.定義一個無參建構函式的作用是什麼?
JAVA程式在執行子類的構造方法之前,如果沒有用super()來呼叫特定的父類構造方法,那麼就會呼叫父類的無參建構函式,因此如果父類中沒有無參建構函式,並且子類沒有使用super()來呼叫特定的父類建構函式的話,將在編譯時發生錯誤,原因是無法在父類中找到可執行的無參構造方法,所以要在父類中加入一個無參建構函式
13.成員變數和區域性變數的區別
- 成員變數可以被public private static等修飾符所修飾,而區域性變數不能被修飾,但是兩者都可以被final修飾
- 從變數在記憶體中的儲存位置來看,成員變數跟物件一樣儲存在堆中,但是區域性變數儲存在棧中,方法呼叫完即消失
- 成員變數如果建立時沒有被手動賦值,則會以型別的預設值賦值,而區域性變數不會被自動賦值
14.類的構造方法的作用是什麼?不手動寫構造方法的話,程式可以執行嗎?
構造方法的作用是對這個類的例項進行初始化,不寫的話,程式會自動加上一個預設的無參建構函式
15.物件相等和引用相等,兩者有什麼不同?
物件相等比較的是記憶體中存放的內容是否相等,而引用相等比較的是兩個引用指向的記憶體地址是否相等