iT邦幫忙

2022 iThome 鐵人賽

DAY 13
0
Software Development

大學耍廢的我要學Java翻身系列 第 13

Day13: Java的封裝和例外處理

  • 分享至 

  • xImage
  •  

封裝(Encapsulation)

物件導向的最後一個重點(繼承抽象多型封裝)
這個部份說的就是我們把資料包在一起,它是個保護機制,防止資料被隨意存取
我們會盡量把我們的屬性設定為private,如果要從外部更改存取,則會去使用setter and getter 方法

未使用封裝的情況

// Main.java
public class Main {
    public static void main(String[] args){
        Dog dog = new Dog("Jack", 5);
        dog.age = -5;   // 有人隨意亂改
        System.out.println("Dog " + dog.name + " is " + dog.age + " years old.");
    }
}
// Dog.java
public class Dog {
    public String name;
    public int age;

    public Dog(String name, int age){
        this.name = name;
        this.age = age;
    }
}

因為這裡dog的屬性是public 所以可以隨意被更改,或是可能改錯,但也造成我們dog的年紀被亂改成-5歲

使用封裝後

// Main.java
public class Main {
    public static void main(String[] args){
        Dog dog = new Dog("Jack", 5);
//         dog.age = -5;   // 不可以被隨意亂改,或是不小心改錯
//        System.out.println("Dog " + dog.name + " is " + dog.age + " years old.");     // 資料不可以被隨意存取
        dog.setAge(-5); // sout error
        dog.setAge(6);  // 長大一歲了!!
        System.out.println("My liitle Dog " + dog.getName() + " is " + dog.getAge() + " years old!!");
    }
}
public class Dog {
    private String name;  // 將name和age設定為private,防止直接的存取
    private int age;

    public Dog(String name, int age){
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age <= 0){      // 設定正確數值區間
            System.out.println("Age Error!!");
        } else {
            this.age = age;
        }
    }
}

例外處理(Exception)

我們寫code常常會遇到一些Bug,但有時候我們只是遇到衣些會造成我們程式執行上的麻煩
所以需要去進行例外的處理,像是跳過它或是改變結果

try {
    // 有可能引發例外的code
} catch (例外種類1 變數1){
    // 處理例外的code
} catch (例外種類2 變數2){
    // 處理例外的code
}

如果輸入的值是不是數字的話,會無法進行

import java.util.Scanner;

// Main.java
public class Main {

    int age;
    String ageStr;

    public Main(){
        Scanner scn = new Scanner(System.in);
        System.out.println("What's your age?");
        ageStr = scn.next();
        age = Integer.parseInt(ageStr);

        if (age < 18){
            System.out.println("You cannot drink!!");
        } else {
            System.out.println("Let's dink all night!!");
        }
    }
    public static void main(String[] args){
        new Main();
    }
} 

我們把它的Exception 抓出來進行例外處理

import java.util.Scanner;

// Main.java
public class Main {

    int age;
    String ageStr;

    public Main(){
        Scanner scn = new Scanner(System.in);
        System.out.println("What's your age?");
        try {
            ageStr = scn.next();
            age = Integer.parseInt(ageStr);

            if (age < 18){
                System.out.println("You cannot drink!!");
            } else {
                System.out.println("Let's dink all night!!");
            }
        } catch (NumberFormatException e){
            e.printStackTrace();    // 直接找出問題點
            System.out.println("Invalid input, please give me a valid input later.");
            new Main();  // 重新輸入數值
        }
    }
    public static void main(String[] args){
        new Main();
    }
}

printStackTrace()就是印出例外的列表
https://ithelp.ithome.com.tw/upload/images/20220927/20137192DNUuPwlYeH.png

常見的例外處理

  1. 運算時,除數為0 => ArithmeticException
  2. 用Null Object執行方法 => NullPointException
  3. index超過array長度限制 => ArrayIndexOutOfBoundsException
public static void main(String[] args){
        int[] arr = {1, 2, 3};
        System.out.println(arr[3]);   // java.lang.ArrayIndexOutOfBoundsException
    }

Throw => 語句拋出一個Exception,throw之後的敘述不會執行

// Main.java
public class Main {
    public static void main(String[] args){
        Dog dog = new Dog("Jack", 5);
//         dog.age = -5;   // 不可以被隨意亂改,或是不小心改錯
//        System.out.println("Dog " + dog.name + " is " + dog.age + " years old.");     // 資料不可以被隨意存取
        try {
            dog.setAge(-5);
        } catch (IllegalArgumentException e){
            System.out.println("Cannot set age!!");
        }
        System.out.println("My liitle Dog " + dog.name + " is " + dog.getAge() + " years old!!");
    }
}
// Dog.java
public class Dog {
    public String name;
    private int age;

    public Dog(String name, int age){
        this.name = name;
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age <= 0){
            throw new IllegalArgumentException("Age cannot to be lower than 0!!");
        } else {
            this.age = age;
        }
    }
}

Throws => 是方法先聲明可能會出現的Exception再去跳過它

// Main.java
public class Main {
    public static void main(String[] args){
        Dog dog = new Dog("Jack", 5);
        try {
            dog.setAge(-5);
        } catch (IllegalArgumentException e){
            System.out.println("Cannot set age!!");
        }
        System.out.println("My liitle Dog " + dog.name + " is " + dog.getAge() + " years old!!");
    }
}
// Dog.java
public class Dog {
    public String name;
    private int age;
    public Dog(String name, int age){
        this.name = name;
        this.age = age;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) throws IllegalArgumentException {
        if (age <= 0){
            throw new IllegalArgumentException("Age cannot to be lower than 0!!");
        } else {
            this.age = age;
        }
    }
}

上一篇
Day12: Java物件導向: 介面
下一篇
Day14: 常見例外和集合
系列文
大學耍廢的我要學Java翻身30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言