一、封裝
- 概念:盡可能的隱藏物件內部的事先細節,控制物件的修改及訪問權限,使得程式不能被外部隨意訪問,提高了安全性,
- 封裝使用訪問修飾符private(可將屬性修飾為私有,僅在本類中可訪問)
- 封裝以后提供get、set方法讓外界呼叫,我們也可以在get和set方法中指定相應規則來規范程式
//////////////////////////////未封裝的代碼//////////////////////////////////////////////// public class Demo01 { public static void main(String[] args) { Stu stu01 = new Stu(); stu01.name = "張三"; stu01.age = 23; stu01.show(); Stu stu02 = new Stu(); stu02.name = "李思思"; // 年齡的范圍符合語法,但是不符合生產需求 stu02.age = 2444; stu02.show(); } } class Stu{ // 屬性 String name; int age; String gender; String addr; // 方法 public void show() { System.out.println("我的名字是" + name + ",我今年" + age); } } //////////////////////////////封裝后的代碼//////////////////////////////////////////////// public class Demo02 { public static void main(String[] args) { Student s01 = new Student(); s01.name = "王五"; s01.setAge(25); s01.show(); } } class Student{ // 屬性 String name; // 私有化屬性age private int age; public void setAge(int age) { this.age = age; } public int getAge() { return this.age; } // 方法 public void show() { System.out.println("我的名字叫" + name + ",我今年" + age); } } -
set和get方法被繞過的情況
- 我們創建物件的時候有可能是呼叫的有引數的構造方法
- 在構造方法中可以直接給屬性完成賦值的操作
- 這樣就繞過了set和get中自定義的規則
- 如果想要set和get中的規則繼續生效的話,在構造方法中呼叫set和get方法
-
1 class Students{ 2 // 屬性 3 String name; 4 private int age; 5 6 // 構造方法 7 public Students() { 8 super(); 9 } 10 11 public Students(String name, int age) { 12 super(); 13 // 構造方法可以逃過set和get方法直接給屬性賦值 14 this.name = name; 15 // 如果想要set中的規則繼續生效就在構造方法中呼叫set和get方法 16 this.setAge(age); 17 }
二、繼承
- 概念:子類從父類中獲取的屬性和方法;子類通過關鍵字extends和這個類產生繼承關系;類和父類需要滿足一個條件【子類 is a 父類】
- 語法格式: class 子類 extends 父類{ 子類的代碼 }
- 繼承的特點:
- Java是單繼承【一個類只能有一個直接的父類,但父類中可以在有父類】
- Java可以多級繼承,子類可以獲取到父類屬性和方法,也可以獲取到父類的父類的屬性和方法
- 優點:提高了代碼的復用性,又提高代碼的可擴展性
- 不可繼承:
- 父類的構造方法不可繼承【由于類的構造方法只負責本類物件,所以不可繼承】
- private修飾的屬性和方法不可繼承【private修飾的屬性和方法作用范圍只限于本類,因此不可繼承】
- 父子類不在同一個package中時,default修飾的屬性和方法:【default修飾的屬性和方法作用范圍僅在同包下】
- 圖解【訪問修飾符】
| 本類 | 同包 | 非同包子類 | 其他 | |
| private | true | false | false | false |
| default | true | true | false | false |
| protected | true | true | true | false |
| public | true | true | true | true |
三、方法重寫\覆寫【Override】==》有繼承關系
- 概念:子類繼承父類的屬性和方法時,父類的方法無法滿足子類的需求,可在子類中定義和父類相同的方法進行重寫【Override】 重寫的原則【可使用@Override注解來驗證是否重寫】
- 方法名稱、引數串列、回傳值型別必須和父類相同
- 訪問修飾符可與父類相同或比父類更廣
- 方法重寫執行:
- 子類重寫父類方法后,呼叫時優先執行子類重寫后的方法
- 案例:
1 public class Demo01 { 2 public static void main(String[] args) { 3 // 方法重寫案例 4 WeChatV1 w01 = new WeChatV1(); 5 w01.chat(); 6 7 WeChatV2 w02 = new WeChatV2(); 8 w02.chat(); 9 10 } 11 } 12 13 class WeChatV1{ 14 public void chat() { 15 System.out.println("微信第一版跨時代產品上市,能通過網路發訊息,發訊息免費."); 16 } 17 } 18 19 classs WeChatV2 extends WeChatV1{ 20 @Override 21 public void chat() { 22 System.out.println("微信第二版隆重上市,可以通過網路發送語音訊息,每人每天可免費發出200條"); 23 } 24 }
四、關鍵字super
- 定義:子類繼承父類后,獲取到父類的屬性和方法有可能與子類的屬性和方法重名,使用super可區分子類與父類的屬性和方法
- super呼叫屬性和方法
- super.方法名(引數串列)==》呼叫父類的方法
- super.屬性名==》呼叫父類的屬性
- super呼叫父類的構造方法
- super(引數串列)==》呼叫父類構造方法
- 案例:
1 class Dog extends Animal{ 2 public Dog() { 3 //呼叫無參構造 4 super(); 5 } 6 7 public Dog(String type, String name, int age, String gender) { 8 // 呼叫父類有引數的構造方法 9 super(type, name, age, gender); 10 } 11 }
- this和super
- 呼叫屬性
- this.屬性 == 》呼叫子類自己的屬性
- super.屬性 ==》呼叫父類的屬性
- 呼叫方法
- this.方法名(引數串列)==》呼叫子類自己的方法
- super.方法名(引數串列)==》呼叫父類的方法
- 呼叫構造方法
- this(引數串列)==》 呼叫子類自己的構造方法
- super(引數串列)==》呼叫父類的構造方法
- 注意:
- 在呼叫構造方法的時候,this和super不能同時存在
- 子類的構造方法會默認呼叫父類的空參構造方法
- this和super必須放在首行
- 呼叫屬性
五、多型
- 概念:父類參考指向子類物件,從而產生多型
- 語法格式:Animal a = new Dog(); ==》Animal:父型別別(參考);Dog():子類物件(物件型別)
- 二者具有直接或間接的繼承關系時,父類參考可指向子類物件,即形成多型,
- 父類參考僅可呼叫父類所宣告的屬性和方法,不可呼叫子類的獨有屬性和方法
- 多型使用方法和屬性呼叫情況:
- 呼叫方法:
- 編譯時候看父類中是否有這個方法,運行時看子類是否重寫過該方法,【編譯看左邊,運行看右邊】
- 呼叫屬性:
- 編譯時候看父類是都存在該屬性,運行時候也是看父類是否存在該方法,【編譯看左邊,運行看左邊】
- 呼叫方法:
六、向上轉型【裝箱】和向下轉型【拆箱】
- 向上轉型【裝箱】
- 宣告的參考是父型別別,回傳比較大,參考指向了子類物件
- 子類物件自動提升為父型別別,不會報錯
- 但是只能使用宣告的父型別別中的屬性和方法
- 多型基本使用情況:Animal a = new Dog();
- 宣告的參考是父型別別,回傳比較大,參考指向了子類物件
- 向下轉型【拆箱】
- 宣告的型別是子型別別的參考
- 參考指向的父型別別的物件
- 如果父型別別參考指向的子型別別的本身,代碼不會出現問題,因為轉了回來
- 如果父類參考的不是子類的型別,會報錯:ClassCastException
- 例如 Dog d = (Animal)Aniimal(); Animal是Dog父類不報錯; Dog d = (Person)Person(); Person不是Dog父類 程式報錯ClassCastException();
- 宣告的型別是子型別別的參考
七、Instanceof
- 定義:判斷一個物件是否是指定型別的實體
- 案例
1 import java.util.Scanner; 2 3 public class Demo06 { 4 public static void main(String[] args) { 5 /** 6 * 傳入一個物件,呼叫這個物件所有的方法 7 */ 8 System.out.println("" instanceof String); 9 10 /** 11 * 提示用書輸入一個數字,呼叫getPerson方法,獲取這個數字對應的物件 12 * 呼叫show方法,傳入這個物件,展示這個物件的方法 13 */ 14 15 Scanner in = new Scanner(System.in); 16 System.out.println("請輸入你希望看到的職業(1==SoftwareEngineer,,,2==DBA,,,3==ImplementationEngineer,,,其他數字==Person):"); 17 int num = in.nextInt(); 18 // 呼叫getPerson方法獲取物件 19 Person person = getPerson(num); 20 21 // 呼叫show方法傳入Person,展示這個職業的方法 22 show(person); 23 24 } 25 26 /** 27 * 傳入數字,獲取對應的Person或者其子類的物件 28 * @param num- 29 * @return 30 */ 31 public static Person getPerson(int num) { 32 Person person; 33 switch (num) { 34 case 1: 35 person = new SoftwareEngineer(); 36 break; 37 38 case 2: 39 person = new DBA(); 40 break; 41 42 case 3: 43 person = new ImplementationEngineer(); 44 break; 45 46 default: 47 person = new Person(); 48 break; 49 } 50 51 return person; 52 } 53 54 55 /** 56 * 展示Person或者其子類的所有方法 57 * @param person 58 */ 59 public static void show(Person person) { 60 if (person == null) { 61 System.out.println("Person為null,請重新執行代碼傳入正確的引數..."); 62 return; 63 } 64 65 // person非null 66 if (person instanceof SoftwareEngineer) { 67 SoftwareEngineer engineer = (SoftwareEngineer) person; 68 engineer.eat(); 69 engineer.sleep(); 70 engineer.work(); 71 } else if (person instanceof DBA) { 72 DBA dba = (DBA) person; 73 dba.eat(); 74 dba.sleep(); 75 dba.eatBraisedChicken(); 76 } else if (person instanceof ImplementationEngineer) { 77 ImplementationEngineer engineer = (ImplementationEngineer) person; 78 engineer.eat(); 79 engineer.sleep(); 80 engineer.work(); 81 } else if (person instanceof Person) { 82 person.eat(); 83 person.sleep(); 84 } else { 85 System.out.println("您選擇的職業暫無相關資訊..."); 86 } 87 } 88 } 89 90 /** 父類 91 * 會有一些子類,子類是具體職業的人 92 * 93 */ 94 class Person{ 95 public void eat() { 96 System.out.println("人類需要吃飯..."); 97 } 98 99 public void sleep() { 100 System.out.println("人需要睡眠保持精力..."); 101 } 102 } 103 104 /** 105 * 技術總監/經理 106 * 技術支持/維護 技術專員 107 * 助理 軟體工程師 108 * 程式員 109 * 硬體工程師 110 * 質量工程師 111 * 測驗工程師 112 * 系統架構師 113 * 資料庫管理/DBA 114 * 游戲設計 115 * 開發 116 * 網頁設計/制作 117 * 語音/視頻/圖形 118 * 專案經理/主管 119 * 產品經理/專員 120 * 網站運營 121 * 網站編輯 122 * 網站策劃 123 * 網路管理員 網路與資訊安全工程師 實施工程師 通信技術工程師 124 * */ 125 126 /** 127 * 軟體工程師類 128 * 繼承Person 129 * 重寫eat和sleep方法 130 * 自定義work方法 131 * @author Dushine2008 132 * 133 */ 134 class SoftwareEngineer extends Person{ 135 136 @Override 137 public void eat() { 138 System.out.println("我們作業很忙,外賣解決吃飯的問題..."); 139 } 140 141 public void sleep() { 142 System.out.println("我們每天堅持午睡,下午精力充沛..."); 143 } 144 145 public void work() { 146 System.out.println("我們的作業白天不怎么忙,晚上經常加班..."); 147 } 148 } 149 150 /** 151 * DBA類 152 * 繼承Person 153 * 重寫eat和work 154 * 自定義eatBraisedChicken方法 155 * @author Dushine2008 156 * 157 */ 158 class DBA extends Person { 159 160 @Override 161 public void eat() { 162 System.out.println("DBA資料庫方面的造詣比較深厚,他們吃飯也是點外賣,靠入侵外賣平臺的資料庫,篡改訂單資訊吃飯."); 163 } 164 165 public void sleep() { 166 System.out.println("中午不睡下午崩潰,堅持在你午睡攻陷你家的資料庫."); 167 } 168 169 public void eatBraisedChicken() { 170 System.out.println("靠技術吃黃燜雞,吃了整整一年..."); 171 } 172 173 } 174 175 /** 176 * 實施工程師 177 * 繼承Person 178 * 重寫eat和sleep方法 179 * 自定義work方法 180 * @author Dushine2008 181 * 182 */ 183 class ImplementationEngineer extends Person{ 184 @Override 185 public void eat() { 186 System.out.println("經常出差,可以領略各地的美食..."); 187 } 188 189 @Override 190 public void sleep() { 191 System.out.println("一年到頭就處于開房和退房的路上..."); 192 } 193 194 public void work() { 195 System.out.println("這是個根客戶打交道比較多的作業..."); 196 } 197 }
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/29067.html
標籤:Java
上一篇:Java面向物件
