Java基础--面向对象以及相关知识
一、 面向對象特征與原則
1、三大特征:封裝、繼承、多態。
(1)封裝:將客觀的事物封裝成抽象的類,封裝代碼邏輯,并通過訪問控制符來控制訪問的方式,從而保護程序(使用反射時,可以獲取對象的私有方法和成員,會破壞封裝性)。
(2)繼承:某個類通過繼承可以獲取另外一個類的方法和屬性(包括私有方法和私有屬性),對于父類私有的方法和私有屬性,子類只是擁有,無法去訪問。同時可以編寫屬于自己的方法,便于程序的擴展。
(3)多態:指一個類的實例的相同方法在不同的情形下有不同的結果。一般與繼承、重寫、向上轉型等概念相關。
2、五大原則:單一職責原則、開放封閉原則、里氏替換原則、依賴倒置原則(多用于框架)、接口分離原則。
3、任一事物均可抽象為對象,事物狀態可以抽象為對象的變量,事物的行為可以抽象為對象的方法,類似的多個對象可以歸為一類。簡單的講,類是對象的模板,對象是類的實例。
?
二、構造方法、方法重載(overload)與方法重寫(override)
1、構造方法,通過構造方法實現對象的初始化,若沒寫構造方法,則系統默認提供一個無參構造。
格式:
(1)構造方法的名稱必須與類名相同。
(2)構造方法沒有返回值,但是也不能用void修飾。
(3)子類繼承父類時,構造方法中最好使用super關鍵字來調用父類的構造方法。若子類中沒寫,那么編譯器會自動加入super(),且此時若父類中沒有無參構造方法,會報錯。
2、方法重載,出現在同一類中,其方法名相同,但參數類型或者參數個數不同。
3、方法重寫,出現在子類中,其方法名,參數類型,參數個數,返回類型與父類相同,且方法的訪問修飾符要比父類的方法權限高。
4、重載與重寫的區別:
(1)重載為編譯期綁定,即編譯時根據參數變量的類型、個數來判斷應該調用哪個方法。
(2)重寫為運行期綁定,即運行時根據引用變量實際指向的對象調用方法。即實例是誰,就調用誰的方法。
5、?由static修飾的方法,屬于靜態方法,編譯、運行時根據引用類型來判斷,即引用類型是誰,就調用誰的方法。
1 /** 2 * 父類 3 */ 4 class Father { 5 public void talk() { 6 System.out.println("This is father"); 7 } 8 9 public static void run() { 10 System.out.println("Running"); 11 } 12 13 } 14 15 /** 16 * 子類 17 */ 18 class Son extends Father { 19 public void talk() { 20 System.out.println("This is son"); 21 } 22 23 public static void run() { 24 System.out.println("Swimming"); 25 } 26 } 27 28 /** 29 * 演示類 30 */ 31 class Demo { 32 public void show(Father obj) { 33 System.out.println("Father"); 34 obj.talk(); 35 } 36 37 public void show(Son obj) { 38 System.out.println("Son"); 39 obj.talk(); 40 } 41 } 42 43 /** 44 * 測試類,演示成員函數與類函數的編譯、運行時的區別 45 * 46 * 測試結果為: 47 * Father 48 * This is father 49 * Son 50 * This is son 51 * Father 52 * This is son 53 * Running 54 * Swimming 55 * Running 56 */ 57 public class Test { 58 public static void main(String[] args) { 59 Father father = new Father(); // 實例化一個Father對象 60 Son brother = new Son();// 實例化一個Son對象 61 Father sister = new Son();// 向上轉型,實例化一個Father對象 62 63 Demo demo = new Demo();// 實例化一個演示類 64 demo.show(father);// 由于方法重載,father屬于Father類,故執行第一個show方法,執行Father類的talk方法。 65 demo.show(brother);// 由于方法重載,brother屬于Son類,故執行第二個show方法,執行Son類的talk方法。 66 demo.show(sister);// 由于方法重載,sister屬于Father類,故執行第一個show方法,但由于方法重寫,執行的是Son類的talk方法。 67 68 // 由static修飾的方法,屬于靜態方法,編譯、運行時根據引用類型來判斷 69 father.run();//引用類型為Father,故相當于執行Father.run(),輸出 Running 70 brother.run();//引用類型為Son,故相當于執行Son.run(),輸出Swimming 71 sister.run();//引用類型為Father,故相當于執行Father.run(),輸出Running 72 } 73 }?
?
三、JVM內存結構(方法區、棧、堆)
1、方法區:方法區用于存放類的信息。當java程序運行時,首先通過類裝載器載入字節碼信息(.class文件),經過解析后將其裝入方法區。即類的各種信息均在方法區保存。
2、棧:棧用于存放程序運行中所有的局部變量。一個java程序運行直到結束的過程中會調用多個方法,而JVM會為每個方法在棧中分配一個對應的空間,這個空間稱為方法的棧幀。棧幀中存儲了該方法的參數、局部變量等數據,當一個方法結束,則清除對應的棧幀。
3、堆:堆用來存放對象,比如使用new關鍵字實例化一個對象,則其相關的成員變量將存于堆中某個區域。
?
四、抽象類、接口、extends、implements、向上造型、instanceof
1、抽象類:使用abstract關鍵字修飾,若方法沒有方法體,必須由abstract關鍵字修飾。不能被實例化,其子類必須重寫所有abstract方法才可以被實例化。
2、接口:使用interface關鍵字修飾,java1.8之前方法沒有方法體,java1.8之后方法可以有方法體,但必須由default關鍵字修飾。不能被實例化,其子類必須重寫所有abstract方法才可以被實例化。
3、通過extends關鍵字實現繼承,子類可以繼承父類的方法以及成員變量,且可以聲明自己的成員變量、方法。
4、通過implements關鍵字實現接口,原理類似繼承。
5、Java不支持多繼承,但可以通過實現多個接口來達到多繼承的效果。一個類可以實現多個接口,一個接口可以繼承多個接口。
6、向上造型:一個子類可以向上造型為父類,即父類的引用指向子類的實例(對象)。比如:Father father = new Son();
7、一個父類的引用可以指向該父類的對象,也可以指向其子類的任意一個對象。可通過instanceof關鍵字可以判斷某變量具體指向的數據類型。
?
五、訪問控制符
1、private:只能在本類中訪問。
2、default:可以在本類以及同包中訪問。即private + 同包。
3、protected:可以在本類、同包、以及子類中訪問。即default + 子類。
4、public:可以在任意一個地方訪問。即protected + 不同包。
?
六、static、final關鍵字
static關鍵字:
1、static修飾成員變量:
(1)static修飾的成員變量不屬于對象的數據結構。
(2)static變量屬于類的變量,通過(類名.變量名)來訪問。
(3)static變量存在方法區中,不在堆里。
(4)一個類只用一份static變量,無論創建多少個對象,此變量均共享。
2、static修飾方法:(類似于修飾成員變量)
(1)static方法屬于類的方法,直接使用(類名.方法名)調用。
(2)通常用于提供一些工具方法、工廠方法等。
3、static修飾代碼塊:(類似于修飾成員變量)
?
final關鍵字:
1、final修飾類:
final修飾的類不能被繼承。
2、final修飾方法:
final修飾的方法不能被重寫。
3、final修飾成員變量:
該成員變量需在初始化時賦值,對象創建后不可被修改,通常用于聲明常量。
?
七、參數傳值(值傳遞還是引用傳遞?)
1、對于基本類型,參數傳遞指的是值傳遞。其傳遞的是參數的復制值,即將參數拷貝一份再傳入,此時修改參數是對拷貝的值進行修改,不會影響原來的值。
2、對于引用類型,參數傳遞可以理解為引用傳遞,也可以理解為值傳遞。其傳遞的是參數的地址的復制值,即將參數的地址拷貝一份再傳入,此時若通過參數(引用地址)修改參數的值,會影響原來的值。若修改參數(引用地址),則不會影響原來的值。
1 /** 2 * 測試類,用于測試參數傳遞為引用傳遞還是值傳遞。 3 * 測試結果為: 4 * hello 5 * hello world 6 * hi 7 * hi 8 */ 9 public class Test { 10 public static void main(String[] args) { 11 StringBuilder str = new StringBuilder("hello"); 12 System.out.println(str); //輸出為hello 13 test1(str); //由于引用傳遞,將str所指向的地址拷貝,通過地址修改地址上的參數,所以會修改地址上的參數。 14 System.out.println(str);//輸出為hello world 15 16 String str1 = "hi"; 17 System.out.println(str1);//輸出為hi 18 test2(str1);//由于引用傳遞,將str1的地址拷貝,由于String的不可變性,其會導致拷貝后的地址重新指向另一個地址,故不會修改原地址上的參數 19 System.out.println(str1);//輸出為hi 20 21 } 22 23 /** 24 * 將參數的地址拷貝,并根據參數的地址,向參數中追加字符串。 25 * 此時原地址的參數被修改。 26 * @param str 27 */ 28 public static void test1(StringBuilder str) { 29 str.append(" world"); 30 } 31 32 /** 33 * 將參數的地址拷貝,由于String的不可變性,所以拷貝的地址將被替換為一個新的地址,新的地址指向"world"參數。 34 * 即相當于給拷貝的地址修改了地址,不會對原有的地址造成影響。 35 * 此時原地址未被修改,且參數未被修改。 36 * @param str 37 */ 38 public static void test2(String str) { 39 str = "world"; 40 } 41 }?
八、異常類(java.lang.Throwable)
1、Throwable類的子類為Exception與Error兩類,其中Error指運行環境出錯,即虛擬機級別的錯誤,如內存溢出。而Exception指程序級別的錯誤,如網絡故障,文件損壞,設備錯誤,輸入非法等。
2、?異常就是程序運行時可能出現的錯誤,而異常處理將會改變程序的控制流程。
3、Java通過throw關鍵字拋出一個Exception子類的實例(即拋出異常對象)表示異常的發生,通過throws關鍵字拋出異常類。
4、java允許定義方法時聲明該方法調用過程中可能出現的異常,即允許方法調用過程中拋出異常對象,從而終止當前方法的執行。
5、異常類中的方法:
public String getMessage();//查看錯誤信息
public void printStackTrace();//輸出執行堆棧信息,跟蹤異常事件的發生。
public String toString();//輸出異常類的信息
Throwable getCause(); 獲取異常產生的真實原因,實際開發中,為了拋出異常的風格統一,通常將實際異常包裝后再拋出,可以通過getCause獲取真實原因。
6、異常處理方式:
(1)捕捉:
try {
需要被檢測的代碼;
}?catch(異常類 變量名) {
異常處理代碼;
}finally {
一定會執行的代碼;(除非程序因某原因退出,比如System.exit(0))
}
· (2)拋出:
throw 關鍵字拋出一個異常類實例, 比如 throw new Exception(e);
throws 關鍵字拋出一個異常類,寫在方法上, 比如 public static void run() throws Exception(){}
7、對于try-catch-finally中出現return的情況,若finally中無return,則返回try或catch中return的結果。若finally中有return,則返回finally中return的結果。
8、自定義異常,需要繼承Exception類或RuntimeException,然后通過throw,throws關鍵字來拋出異常。
9、異常分類:
(1)運行時異常(非檢查異常):指RuntimeException及其子類,不需要檢查(即編譯器不處理),一旦出錯,程序將停止運行。
(2)編譯時異常(檢查異常):除RuntimeException外的異常,需要檢查并處理,否則會編譯失敗。
1 public class Test {2 public static void main(String[] args) {3 try {4 run();5 } catch (RuntimeException e) {6 System.out.println(e.getMessage());// 輸出實際異常,java.lang.NullPointerException7 System.out.println(e.toString());// 輸出所有異常,java.lang.RuntimeException:8 // java.lang.NullPointerException9 System.out.println(e.getCause());// 打印實際的異常,java.lang.NullPointerException 10 } 11 12 System.out.println(demo1());// finally中無return,且未拋出異常,執行try代碼,finally代碼后,輸出0. 13 System.out.println(demo2());// finally中無return,且拋出異常,執行catch代碼,finally代碼后,輸出1. 14 System.out.println(demo3());// finally中有return,且未拋出異常,執行try代碼,finally代碼后,輸出2. 15 System.out.println(demo4());// 程序中途退出,沒有輸出結果 16 } 17 18 public static void run() throws RuntimeException { 19 try { 20 String str = null; 21 System.out.println(str.length());// 空指針異常 22 } catch (NullPointerException e) { 23 // 將異常包裝一下,throw關鍵字拋出一個異常類的實例,由throws關鍵字拋出異常類 24 throw new RuntimeException(e); 25 } 26 } 27 28 public static int demo1() { 29 try { 30 return 0; 31 } catch (NullPointerException e) { 32 return 1; 33 } finally { 34 // return 2; 35 } 36 } 37 38 public static int demo2() { 39 try { 40 String str = null; 41 System.out.println(str.length());// 空指針異常 42 return 0; 43 } catch (NullPointerException e) { 44 return 1; 45 } finally { 46 // return 2; 47 } 48 } 49 50 public static int demo3() { 51 try { 52 return 0; 53 } catch (NullPointerException e) { 54 return 1; 55 } finally { 56 return 2; 57 } 58 } 59 60 public static int demo4() { 61 try { 62 System.exit(0); 63 return 0; 64 } catch (NullPointerException e) { 65 return 1; 66 } finally { 67 return 2; 68 } 69 } 70 }?
轉載于:https://www.cnblogs.com/l-y-h/p/10899374.html
總結
以上是生活随笔為你收集整理的Java基础--面向对象以及相关知识的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JavaScript 转载
- 下一篇: Java : Hibernate 动态+