S SmartDocs
Series: Angelia java 64 lines · Updated 2026-09-27

Main.java

Angelia/Java/Week_6_7/code/01_encapsulation/Main.java

/**
 * 01_encapsulation 示範程式。
 *
 * 編譯與執行:
 *   javac *.java
 *   java -ea Main
 */
public class Main {

    /**
     * 這個方法只認識 Account 介面:
     * 不管傳進來的是 BankAccount、PointsAccount 還是 PremiumPointsAccount,都能正常運作。
     */
    static void handleAccount(Account a) {
        System.out.println("  餘額:" + a.getBalance());
        a.deposit(500);
        System.out.println("  存入 500 後:" + a.getBalance());
    }

    public static void main(String[] args) {
        System.out.println("=== 1. 封裝:只能透過方法改變狀態 ===");
        BankAccount acct = new BankAccount(100);
        acct.deposit(50);
        acct.withdraw(30);
        System.out.println("  餘額 = " + acct.getBalance());        // 120
        assert acct.getBalance() == 120;
        // acct.balance = -500;   // 編譯錯誤!balance 是 private,這正是封裝的目的

        System.out.println("=== 2. 例外:違反前置條件時立刻失敗 ===");
        try {
            acct.withdraw(1000);                                 // 餘額不足
        } catch (IllegalStateException e) {
            System.out.println("  攔到 IllegalStateException:" + e.getMessage());
        }
        try {
            acct.deposit(-5);                                    // 負數存款
        } catch (IllegalArgumentException e) {
            System.out.println("  攔到 IllegalArgumentException:" + e.getMessage());
        }
        assert acct.getBalance() == 120 : "失敗的操作不應改變狀態";

        System.out.println("=== 3. 介面:同一段程式碼處理不同實作 ===");
        System.out.println(" BankAccount:");
        handleAccount(new BankAccount(0));                       // 0 → 500
        System.out.println(" PointsAccount:");
        handleAccount(new PointsAccount());                      // 10000 → 10505

        System.out.println("=== 4. 動態分派:看的是「執行期」的型別 ===");
        PointsAccount p = new PremiumPointsAccount();            // 靜態型別 PointsAccount
        p.deposit(500);                                          // 執行 Premium 版:550 + 5 = 555
        System.out.println("  PremiumPointsAccount 存 500 → " + p.getBalance());
        assert p.getBalance() == 10555;

        Account[] accounts = {
            new BankAccount(10), new PointsAccount(), new PremiumPointsAccount()
        };
        for (Account a : accounts) {
            a.deposit(100);          // 每個元素各自跑自己類別的 deposit
            System.out.println("  " + a.getClass().getSimpleName()
                    + " → " + a.getBalance());
        }
        System.out.println("全部完成。");
    }
}

Related articles