<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # Java封裝 [TOC] ## 導學 在之前的課程中,我們已經對Java的面向對象開發有了一些了解。那么本章節,我們就來看看面向對象三大特性之一的封裝。 所謂封裝,就是將類的某些信息隱藏在類的內部,不允許外部程序直接訪問 ,只能通過該類提供的方法來實現對隱藏信息的操作和訪問。 簡單來說,既要隱藏對象的信息,也要留出訪問的接口。 封裝的特點在于: 1. 只能通過規定的方法訪問數據 2. 隱藏類的實例細節,方便修改和實現 ## 封裝的實現 對于如何實現封裝,我們可以通過以下三個步驟: ![](https://img.kancloud.cn/bb/d2/bbd20ce2232f818ee860cf9f9c0cdfa6_651x455.png) 在之前的課程中,我們使用了寵物貓這個例子,那么這個寵物貓的年齡可以由我們自由的設置,那么如果我們給寵物貓的年齡設置為負值,則就不符合現實的邏輯了。 ### 修改屬性的可見性 ~~~ public class Cat { //將屬性的訪問控制修飾符修改為private-限定只能在當前類內被訪問 private String name; private int month; private double weight; private String species; } ~~~ `private`修飾的屬性只能在當前類中進行操作和訪問,在本類之外,是不允許被直接訪問的。 ### 創建公有的get/set方法 ~~~ public class Cat { //1.將屬性的訪問控制修飾符修改為private private String name; private int month; private double weight; private String species; //2.創建公有的get/set方法 public String getName() { return name; } public void setName(String name) {//傳入相同的參數名與屬性形成對照 this.name = name; } public int getMonth() { return month; } public void setMonth(int month) { this.month = month; } public double getWeight() { return weight; } public void setWeight(double weight) { this.weight = weight; } public String getSpecies() { return species; } public void setSpecies(String species) { this.species = species; } } ~~~ 相關方法名的定義: * get + 首字母大寫的屬性名() :get 方法一般都是具有和屬性數據類型一致的返回值,并且是沒有形參的。 * set + 首字母大寫的屬性名(參數):set 方法一般都是具有和屬性數據類型一致的方法參數,返回值一般是 void。 如果一個屬性只有`get`方法以供獲取的話,我們說該屬性就是一個只讀屬性。如果只有`set`方法以供操作的話,那么該屬性就是一個只寫屬性。 >[success] 在 Eclipse 中,可以通過快捷方式生成相關屬性的 getter 和 setter > 在 「source」-> 「generate getters and setters」 ### 在get/set方法中加入屬性控制 這一步并不是必須的,而是為了針對屬性值進行合理的判斷,防止對屬性值的胡亂操作。 ~~~ /** * 針對年齡范圍作出合理限制 * @param month */ public void setMonth(int month) { if(month < 0 || month >= 240) { System.out.println("年齡不合理,暫定為1"); this.month = 1; } else { this.month = month; } } ~~~ ### 訪問和操作屬性 ~~~ import com.dodoke.obj.animal.*; public class CatTest { public static void main(String[] args) { Cat one = new Cat(); one.setName("凡凡"); one.setMonth(3); one.setWeight(0.5); one.setSpecies("英短"); System.out.println("昵稱:" + one.getName()); System.out.println("月份:" + one.getMonth()); System.out.println("重量:" + one.getWeight()); System.out.println("品種:" + one.getSpecies()); } } ~~~ 對于已經封裝好的類,我們想要操作和訪問其屬性,只有利用其對外暴露的接口`set/get`方法,才能實現。 ### 帶參構造器中的屬性控制 在之前的課程中,我們提到可以使用帶參構造器實現對象實例化時候的屬性設定。 ~~~ //保證類中無論何時都有一個無參構造器 public Cat() { } public Cat(int month) { this.month = month; } =============================== //測試 public static void main(String[] args) { Cat two = new Cat(-3); System.out.println(two.getMonth()); } ~~~ 我們發現上述代碼執行之后,并沒有完成對屬性值的限制,這是因為在構造器中,我們直接對屬性值進行了操作。所以,我們可以利用`set`方法中的屬性限制,完成代碼邏輯。 ~~~ public Cat(int month) { //this.month = month; this.setMonth(month); } ~~~ ## static關鍵字 ![](https://img.kancloud.cn/52/0d/520dee400815fa2e82875aae04b68ffb_739x323.png) 針對于主方法,我們之前也已經介紹過其中的一些知識點,本章節,我們來學習`static`關鍵字的作用。`static`代表著靜態信息。 首先我們通過一段代碼來看一下static的作用 ~~~ public class Cat { //1.將屬性的訪問控制修飾符修改為private private String name; private int month; private double weight; private String species; public static int price;//價格 //2.創建公有的get/set方法 public String getName() { return name; } public void setName(String name) { this.name = name; } public int getMonth() { return month; } /** * 針對年齡范圍作出合理限制 * @param month */ public void setMonth(int month) { if(month < 0 || month >= 240) { this.month = 1; } else { this.month = month; } } public double getWeight() { return weight; } public void setWeight(double weight) { this.weight = weight; } public String getSpecies() { return species; } public void setSpecies(String species) { this.species = species; String str = "男"; if(str.equals("男")) { System.out.println("性別為男"); } else { System.out.println("性別為女"); } } public Cat() { } public Cat(int month) { this.setMonth(month); } } ~~~ ~~~ public class CatTest { public static void main(String[] args) { Cat one = new Cat(); one.setName("花花"); one.setMonth(3); one.setWeight(0.5); one.setSpecies("英短"); one.price = 2000; Cat two = new Cat(); two.setName("凡凡"); two.setMonth(1); two.setWeight(0.4); two.setSpecies("中華田園貓"); two.price = 150; System.out.println("我叫" + one.getName() + ",我的售價是" + one.price); System.out.println("我叫" + two.getName() + ",我的售價是" + two.price); } } ~~~ 上述代碼運行之后,我們會發現兩只貓的售價都是150。這里就是`static`的一個作用了。 `static`表示靜態的,`static`修飾的屬性稱之為【類變量,靜態變量】,方法稱之為【類方法,靜態方法】。 在Java程序中,`static`修飾的成員具有這樣一個特征,無論該類最終實例化出來多少對象,靜態成員都會共用一塊靜態空間。也就是說: ![](https://img.kancloud.cn/e5/2b/e52befaa0fd7da7811d6c9f1090b4080_829x427.png) 無論有多少寵物貓,對于價格而言,它們是共用同一塊靜態空間的。這也就是花花的價格起先是兩千,而在凡凡的價格修改為150之后,兩者的價格都被修改為150了。因為兩者都在針對同一塊內存空間進行操作。 >[warning]對普通成員而言:當這個類的對象產生的時候,它的相關成員會產生,而當這個對象銷毀的時候,這些成員就會進行資源釋放。 >對靜態成員而言:從類第一次加載的時候,靜態成員就會產生,一直到這個類不在有任何對象被使用。也就是它徹底銷毀的時候,靜態資源才會進行資源的釋放。所以靜態成員的生命周期比較長壽。 所以,靜態資源有著如下的特性: * 類對象共享 * 類加載時產生,銷毀時釋放,生命周期長 靜態資源的訪問方式: * 對象.靜態成員 * 類.靜態成員 只是對于使用`對象.靜態成員`的方式調用靜態成員,會出現警告。這是因為本質上,用`static`修飾的成員變量和方法,是屬于**類**的,而不是屬于該**類的實例(對象)**。 | 成員屬性/方法 | 類屬性/方法 | | --- | --- | | 屬于類的成員(對象)的屬性和方法 | 屬于對象共有(類)的屬性和方法 | ### static的修飾內容 `static`用來修飾方法和屬性 ~~~ public static class Cat {}//不能用在類的修飾上 public void eat() { static int a = 5;//注意不能用來修飾局部變量 } ~~~ ### 靜態內容與非靜態內容的訪問限制 1. 在成員方法中,可以直接訪問類中靜態成員 ~~~ public static void eat() { System.out.println("小貓吃魚"); } public void run() { eat(); this.name = "妞妞"; //注意這邊this表示的是正在調用該屬性的對象 //其實也就是使用了==>對象.靜態資源的調用方式 this.price = 20; System.out.println("售價是" + Cat.price + "的" + this.name + "快跑"); } ~~~ 測試: ~~~ public class CatTest { public static void main(String[] args) { Cat one = new Cat(); one.setName("花花"); one.setMonth(3); one.setWeight(0.5); one.setSpecies("英短"); one.price = 2000; Cat.price = 3000; one.run(); } } ~~~ 2. 靜態方法中不能直接訪問同一個類的非靜態成員,只能直接調用同一個類中的靜態成員。 ~~~ public static void eat() { run();//不能調用 this.name = "胖虎";//靜態方法中不能使用this name = "胖虎"; price = 1500;//可以調用 Cat cat = new Cat(); cat.run();//這樣才可以調用 System.out.println("小貓吃魚"); } ~~~ 如果想要訪問非靜態成員,只能通過對象實例化后,`對象.成員方法/屬性`的方式訪問 ### 代碼塊 在Java中,如果在語句當中出現`{}`,這樣的大括號對這就叫代碼塊。 * 普通代碼塊——順序執行 ~~~ public void run(String name) { { System.out.println("我是普通代碼塊1"); }//出現在普通方法中 System.out.println(name + "快跑"); { System.out.println("我是普通代碼塊2"); } } public static void main(String[] args) { Cat one = new Cat(); one.run("花花"); } ~~~ * 構造代碼塊——創建對象時調用,優先于構造方法執行;多個構造代碼塊順序執行; ~~~ public class Cat { //1.將屬性的訪問控制修飾符修改為private private String name; private int month; private double weight; private String species; public static int price;//價格 { System.out.println("我是構造代碼塊1"); }//直接出現在類中 //2.創建公有的get/set方法 public String getName() { return name; } public void setName(String name) { this.name = name; } public int getMonth() { return month; } /** * 針對年齡范圍作出合理限制 * @param month */ public void setMonth(int month) { if(month < 0 || month >= 240) { this.month = 1; } else { this.month = month; } } public double getWeight() { return weight; } public void setWeight(double weight) { this.weight = weight; } public String getSpecies() { return species; } public void setSpecies(String species) { this.species = species; } public Cat() { System.out.println("我是寵物貓~"); } { System.out.println("我是構造代碼塊2"); }//直接出現在類中 public Cat(int month) { this.setMonth(month); } public static void eat() { System.out.println("小貓吃魚"); } public void run(String name) { { System.out.println("我是普通代碼塊1"); }//出現在普通方法中 System.out.println(name + "快跑"); { System.out.println("我是普通代碼塊2"); } } } ~~~ 測試: ~~~ public static void main(String[] args) { Cat one = new Cat(); one.run("花花"); } ======================== 運行結果: 我是構造代碼塊1 我是構造代碼塊2 我是寵物貓~ 我是普通代碼塊1 花花快跑 我是普通代碼塊2 ~~~ * 靜態代碼塊——static修飾的代碼塊,優于構造代碼塊執行,多個靜態代碼塊順序執行;無論產生多少個實例,只調用一次。 ~~~ public class Cat { //1.將屬性的訪問控制修飾符修改為private private String name; private int month; private double weight; private String species; public static int price;//價格 { System.out.println("我是構造代碼塊1"); }//直接出現在類中 //2.創建公有的get/set方法 public String getName() { return name; } public void setName(String name) { this.name = name; } public int getMonth() { return month; } /** * 針對年齡范圍作出合理限制 * @param month */ public void setMonth(int month) { if(month < 0 && month >= 240) { this.month = 1; } else { this.month = month; } } public double getWeight() { return weight; } public void setWeight(double weight) { this.weight = weight; } public String getSpecies() { return species; } public void setSpecies(String species) { this.species = species; } public Cat() { System.out.println("我是寵物貓~"); } static{ System.out.println("我是靜態代碼塊"); } public Cat(int month) { this.setMonth(month); } public static void eat() { System.out.println("小貓吃魚"); } public void run(String name) { { System.out.println("我是普通代碼塊1"); }//出現在普通方法中 System.out.println(name + "快跑"); { System.out.println("我是普通代碼塊2"); } } } ~~~ 僅希望執行一次的代碼就可以放到靜態代碼塊中,這樣可以提高代碼的執行效率。 在普通代碼塊中可以操作類成員,但是在靜態代碼塊中只能操作靜態成員,如果想用需要先實例化對象,通過對象.成員調用。 ### 代碼塊中的變量 ~~~ public void run(String name) { { System.out.println("我是普通代碼塊1"); }//出現在普通方法中 System.out.println(name + "快跑"); { System.out.println("我是普通代碼塊2"); } } ~~~ 這樣一段代碼,實際上形成了三個作用空間。 ![](https://img.kancloud.cn/bf/e9/bfe962ec6376235b51b15a5e2910f9b3_312x462.png) 在之前的局部變量的課程中,我們也講過,一個作用空間中是不允許出現兩個同名變量的。那么在代碼塊中,是否可以出現同名變量呢? ~~~ public void run(String name) { { int temp = 12; System.out.println("我是普通代碼塊1,temp=" + temp); }//出現在普通方法中 System.out.println(name + "快跑,temp=" +temp);//出錯,temp的作用范圍只在大括號內 { int temp = 13; System.out.println("我是普通代碼塊2,temp=" +temp); } } ~~~ 在一個代碼塊運行結束的時候,代碼塊中的局部變量就會被垃圾回收機制自動回收。 ~~~ public void run(String name) { int temp = 14;//以下的temp定義都會出錯。 { int temp = 12; System.out.println("我是普通代碼塊1,temp=" + temp); }//出現在普通方法中 System.out.println(name + "快跑,temp=" +temp);//出錯,temp的作用范圍只在大括號內 { int temp = 13; System.out.println("我是普通代碼塊2,temp=" +temp); } } ~~~ ## 練習 一、選擇 1. 當類中的一個成員方法被下面哪個修飾符修飾后,該方法只能在本類中被訪問 ~~~ A. public B. private C. final D. default ~~~ 2. 運行以下Java代碼,說法正確的是 ![](https://img.kancloud.cn/1c/13/1c136ca3170f68fc42e3d2d45027d3b4_448x195.png) ~~~ A. 15 B. 程序運行正常,但無輸出 C. 編譯報錯 D. 運行報錯 ~~~ 3. java封裝的意義(多選) ~~~ A. 防止使用者錯誤修改系統的屬性 B. 提高系統的獨立性 C. 提高軟件的可重用性 D. 提高構建大型系統的風險 ~~~ 4. 下面代碼的運行結果是 ![](https://img.kancloud.cn/96/e2/96e2519e06403596366168a668d5254b_450x396.png) ~~~ A. 我是一名學生。 B. 我是一個即將大學畢業的學生。 C. 我是一名學生。 我是一個即將大學畢業的學生。 D. 編譯錯誤 ~~~ 5. 關于package+包名;的說法不正確的是 ~~~ A. 一個java源文件可以有多個package語句 B. 建議包名應該全部英文小寫 C. 建議包名命名方式:域名倒敘+模塊+功能 D. "package+包名;"必須放在java源文件中的第一行 ~~~ 6. 下面關于import,class和package的聲明順序哪個是正確的 ~~~ A. package,import,class B. class,import,package C. import,package,class D. package,class,import ~~~ 7. 以下代碼運行結果為: ![](https://img.kancloud.cn/5b/09/5b0967d354af8806843c6bbabedb27af_453x181.png) ~~~ A. 編譯出錯 B. 輸出:c C. 編譯正常,運行時報錯 D. 編譯正常,運行時無輸出結果 ~~~ 8. 下列關于static的說法不正確的是 ~~~ A. 可以定義靜態方法,但不能定義靜態變量 B. class前不可以是用static作為修飾符 C. static可以把普通的成員方法變為一個靜態方法 D. static可以把一個普通方法變為一個類方法 ~~~ 9. 關于靜態方法和非靜態方法,以下描述正確的是 ~~~ A. 非靜態方法只能訪問非靜態變量 B. 靜態方法既可以直接訪問本類的靜態變量,也可以直接訪問本類的非靜態變量 C. 靜態方法在類外只能通過類名來調用 D. 非靜態方法在類外只能通過對象來調用 ~~~ 10. 下面這段代碼中,報錯的地方原因是(多選) ![](https://img.kancloud.cn/c6/2c/c62ca609a74a7508e3082bfc612f7f5c_445x202.png) ~~~ A. 沒有傳入參數 B. 沒有使用類方法來調用 C. 不能使用靜態引用去訪問非靜態的方法 D. 只要實例化對象就不會報錯了 ~~~ 二、編程 1. 編寫自定義類實現圖書信息設置 任務: 屬性:書名、作者、出版社、價格 方法:信息介紹 要求: * 設計構造函數實現對屬性賦值 * 設置私有屬性,get/set方法實現對屬性的訪問 * 限定圖書價格必須大于10,如果無效需進行提示,并強制賦值為10 * 限定作者、書名均為只讀屬性 * 信息介紹方法描述圖書所有信息 ~~~ public class Book { //私有屬性:書名、作者、出版社、價格 //通過構造方法實現屬性賦值 /*通過公有的get/set方法實現屬性的訪問,其中: 1、限定圖書價格必須大于10,如果無效需進行提示,并強制賦值為10 2、限定作者、書名均為只讀屬性 */ //信息介紹方法,描述圖書所有信息 } ~~~ 2. 編寫自定義類實現用戶信息類。 **任務**: * 用戶類: 屬性:用戶名、密碼 * 用戶管理類: 方法:用戶信息驗證 **要求**: ??????1. 設計構造函數實現對屬性賦值 ??????2. 設置私有屬性,get/set方法實現對屬性的訪問 ????? 3. 用戶信息驗證判斷兩個用戶信息是否一致。當用戶名和密碼都一致的時候返回:用戶名和密碼一致,否則返回:用戶名或密碼不一致 **PS**: 字符串的判斷不可以使用`==`進行判斷,可以通過equals()方法進行字符串內容的判斷,如果內容相等返回值為true,反之為false,如當str代表用戶性別時,可以通過如下代碼,判斷性別為“男”還是“女” ![](https://img.kancloud.cn/cf/d7/cfd774dc2eeb79580d18adcfbf07da2a_379x143.png) **代碼運行結果參考**: ![](https://img.kancloud.cn/5f/70/5f7064c00ed9e33d8a940befe691f0c0_189x161.png)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看