Chapter10 Java封裝

董先森發表於2018-03-12

Lecture1 封裝的實現

  • 封裝:將類的某些資訊隱藏在類內部,不允許外部程式直接訪問,只能通過該類提供的方法來實現對隱藏資訊的操作和訪問(即隱藏物件資訊的同時要留出訪問的介面)
  • 封裝的特點:

    1. 只能通過規定的方法訪問資料
    2. 隱藏類的例項細節,方便修改和實現
  • 封裝程式碼的實現:

    1. 修改屬性的可見性 — 設為private
    2. 建立getter/setter方法 — 設為public,用於屬性的讀寫
    3. 在getter/setter方法中加入屬性控制語句

Tips:只有getXXX方法的屬性是隻讀屬性;只有setXXX方法的屬性是隻寫屬性

  • Java封裝的意義:

    • 防止使用者錯誤修改系統的屬性
    • 提高系統的獨立性
    • 提高軟體的可重用性
  • Java封裝案例:
package Chapter10.Lecture1.cat;

/**
 * 寵物貓類的封裝
 */
public class Cat {
    //1.修改屬性的可見性--private,限定只能在當前類內被訪問
    private String name;    //暱稱
    private int month;      //年齡

    public Cat(){

    }

    //通過帶參構造方法賦值
    public Cat(int month) {
        this.setMonth(month);
    }

    //2. 建立getter/setter方法
    public String getName() {
        return "我是一隻叫" + name + "的寵物貓";
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getMonth() {
        return month;
    }

    public void setMonth(int month) {
        if (month <= 0) {
            System.out.println("資訊輸入錯誤,年齡必須大於0");
        } else {
            this.month = month;
        }
    }
}
package Chapter10.Lecture1.cat;

public class CatTest {
    public static void main(String[] args) {
        //物件例項化
        Cat one = new Cat();
        //通過帶參構造方法建立類
        Cat two = new Cat(-2);
        //測試
        //會輸出屬性month的初始值0
        System.out.println("年齡:"+two.getMonth());

        one.setName("花花");
        System.out.println(one.getName());

        one.setMonth(-1);
        if (one.getMonth() == 0) {
            return;
        }
        System.out.println("年齡:" + one.getMonth());
    }
}
  • 定義Java包:語法 — package 包名;,必須放在Java原始檔中的第一行;一個Java原始檔中只能有一個package語句
  • Java包的作用:管理Java檔案;解決同名檔案衝突
  • Java包的特點:Java中一個包裡不能存在同名類,建議每個包內儲存的資訊功能單一
  • Java包的命名:域名倒序+模組名+功能名(推薦全部使用小寫)
  • 匯入包的方法:

    1. 通過import 包名.*;匯入此包下的所有類
    2. 通過import 包名.類名;匯入此包下的指定類
    3. 通過在原始碼中直接載入包名.類名;

建議採用import 包名.類名;的方式載入,提高效率

Tips:載入類的順序跟import匯入語句的位置無關

  • 當通過import 包名.*;只能訪問到指定包名下的類,無法訪問子包下的類
  • Java常用系統包:
java.lang 包含Java語言的基礎的類,該包系統載入時預設匯入,如:System、String、Math
java.util 包含Java語言中常用工具,如:Scanner、Random
java.io 包含輸入、輸出相關功能的類,如File、InputStream

Lecture2 static關鍵字

  • static關鍵字:表示靜態資訊;特徵:類物件共享(即共享同一塊記憶體空間);類載入時產生,銷燬時釋放,生命週期長
  • 靜態成員的訪問方法:

    1. 物件.成員名
    2. 類名.成員名

推薦呼叫方式:類名.靜態成員

  • static + 屬性 — 靜態屬性、靜態屬性;static + 方法 — 靜態方法、類方法;沒有靜態的類(只能使用public、abstract、final修飾)和靜態的區域性變數(只能使用final修飾)
  • 普通成員方法可以呼叫類中任何成員(包括靜態成員),而靜態方法中不能直接訪問同一個類中的非靜態成員,只能直接呼叫同一個類中的靜態成員
  • 程式碼塊:在語句中出現“ {} ”,就叫做程式碼塊;出現在方法裡 — 普通程式碼塊(順序執行 – 先出現,先執行;可以有多個普通程式碼塊 );出現在類中 — 構造程式碼塊(建立物件時呼叫,優先於構造方法執行;可以有多個構造程式碼塊),可以給所有成員賦值;static + 構造程式碼塊 — 靜態程式碼塊(只在類載入時呼叫執行一次,優先於構造程式碼塊執行;可以有多個靜態程式碼塊),只能給靜態成員賦值
  • 變數的作用範圍:從定義處開始至大括號閉合
  • static關鍵字及程式碼塊案例:
package Chapter10.Lecture2.animal;

public class Cat {
    //靜態成員、類成員
    public static int price;   //售價

    private String name;    //暱稱
    private int month;  //年齡
    private double weight;  //體重
    private String species; //品種

    {
        System.out.println("我是構造程式碼塊");
    }

    static {
        System.out.println("我是靜態程式碼塊");
    }

    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;
    }

    public static void eat() {
        //靜態方法中不能直接訪問同一個類中的非靜態成員,只能直接呼叫同一個類中的靜態成員
        //run();
        //name = "小明";
        //只能通過物件例項化後,物件.成員方法的方式訪問非靜態成員
        Cat temp = new Cat();
        temp.run();
        temp.name = "小明";
        //靜態方法中不能使用this
        //this.name = "小明";
        Cat.price = 100;
        System.out.println("小貓吃魚");
    }

    //在成員方法中,可以直接訪問類中的靜態成員
    public void run() {
        {
            System.out.println("我是普通程式碼塊");
        }
        this.name = "凡凡";
        Cat.price = 20;
        eat();//此行程式碼會導致棧溢位,註釋掉後執行(原因:遞迴呼叫)
        System.out.println("售價是" + Cat.price + "的" + this.name + "快跑");
    }
}
package Chapter10.Lecture2.test;

import Chapter10.Lecture2.animal.Cat;

public class Test {
    public static void main(String[] args) {
        Cat one = new Cat();
        one.setName("花花");
        one.setMonth(2);
        one.setSpecies("英國短毛貓");
        //one.price = 2000;
        Cat.price = 2000;

        Cat two = new Cat();
        two.setName("凡凡");
        two.setMonth(1);
        two.setSpecies("中華田園貓");
        //two.price = 150;
        Cat.price = 150;

        System.out.println(one.getName() + "的售價為:" + one.price);
        System.out.println(two.getName() + "的售價為:" + two.price);

        //one.eat();
        Cat.eat();
        System.out.println("----------------------");

        one.run();
    }
}

相關文章