JAVA – 方法、類別與物件

自訂義方法

類似 python裡的 def

格式

// 寫法1 - return 
public static 返回資料型別 name(資料型別 參數, ...) { //自定義def開始的地方
        return ...;
}
// 寫法2 - 沒return
public static void name(資料型別 參數, ...) {
    System.out.println(...);
}
public class IntegerTest {
    public static void main(String[] args) {
        System.out.println(add(1,3));
    }
    
    public static int add(int a, int b) { //自定義def開始的地方
        return a + b;
    }
    
}// int 表示會回傳整數值

不定引數個數 Varargs

使用三個點 ... 表示不定引數,切記 … 只能寫在最後面

void  add(int x, int... y)

不定引數其實是被 Java 編譯器處理成一個 陣列,所以在方法內部,不定引數會被當作一個陣列來使用 所以

public static void printNumbers(int... numbers) {
    for (int num : numbers) {
        System.out.println(num);
    }
}
printNumbers(1, 2, 3); // 印出 1、2、3
printNumbers();        // 不會印出任何東西
printNumbers(10);      // 印出 10

lambda

種簡潔的方式來實作匿名函式

一定要有default

// 寫法1
(parameters) -> expression
// 寫法2
(parameters) -> { statements }

方法多載

同一個類別中,定義多個名稱相同參數不同的方法。

Java 編譯器會根據傳入參數的類型與數量來選擇最適合的方法執行

public class Calculator {
    // 方法多載:加法操作
    public int add(int a, int b) { // 接收兩個整數
        return a + b;
    }
    
    public int add(int a, int b, int c) { // 接收三個整數
        return a + b + c;
    }

    public String add(String a, String b) { // 接收兩個字串
        return a + b;
    }

    public static void main(String[] args) {
        Calculator calc = new Calculator();//建立物件 後面會說到 先別管

        System.out.println(calc.add(10, 20)); // 呼叫 int 版本,輸出 30
        System.out.println(calc.add(10, 20, 30)); // 呼叫三參數版本,輸出 60
        System.out.println(calc.add("Hello", "World")); // 呼叫字串版本,輸出 HelloWorld
    }
}

這裡要介紹一個名詞叫

方法簽名 – Method Signature

義指

  • 方法的名稱
  • 方法的參數列表(數量與型別)

而每個多載的方法 他的方法簽名都要是不同的

方法的返回型別(Return Type)不屬於方法簽名的一部分。

所以下方為錯誤寫法

void method() { }
int method() { }

兩個方法的名稱相同,參數列表相同(都是空參數),而返回型別(voidint)並不被視為方法簽名的一部分。因此,Java 編譯器無法區分這兩個方法,會拋出錯誤。

Java的核心就是物件,導向簡單來說就是可以自訂義的資料型態

假設有個物件是狗,它的特色 如 名字 斑紋 顏色等,而他的行為可以有 跑 坐下 跳高

在物件導向中,

我們就將這隻狗的 特色 稱做 屬性行為 稱作 方法


建立在類別中的自訂義函式

//寫法一 沒有return 
void sleep(){ // 方法
        System.out.println(name+"正在睡覺");
}
//寫法二 return
int Deposit(int x){
        return x;  
}

定義類別

寫在 public class 檔案名 這行的外面

class 類別名稱{
    String name; // 屬性
    void sleep(){ // 方法
        System.out.println(name+"正在睡覺");
    }
}

呼叫類別

透過建構式來創建物件後呼叫( 後面會詳述建構式)

類別名稱 物件名稱 = new 建構式名稱(引數)

執行範例

class Dog { // 宣告類別
    String name;
    void sleep(){
        System.out.println(name+"正在睡覺");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog(); // 建立物件

        myDog.name = "Harry"; // 設定屬性初值
        System.out.println(myDog.name);
        myDog.sleep();//呼叫方法
    }
}

練習

製做銀行帳戶類別 供使用者存入和提出

//輸出結果
存入金額100
目前帳戶餘額:100
存入金額10
目前帳戶餘額:110
取出金額50
目前帳戶餘額:60
// code
class Bank {
    int Balance = 0;

    void Withdraw(int x){
        System.out.println("存入金額"+x);
        System.out.println("目前帳戶餘額:" + (Balance+x ));
        Balance += x ;
    }
    void Deposit(int x){
        System.out.println("取出金額"+x);
        System.out.println("目前帳戶餘額:"+ (Balance-x));
        Balance-=x;
    }
}

public class Main {
    public static void main(String[] args) {
        Bank account = new Bank();
        account.Withdraw(100);
        account.Withdraw(10);
        account.Deposit(50);
    }
}

所以你會發現

我們之前執行的程式碼

其實就是在一個名叫 Main 的class下 的 自訂義 無回傳值 function 執行的

而物件是根據類別所產生的實體(instance)

this

假如你今天寫在類別裡的函式 你傳進去的參數跟你原本的參數撞名

這時候就可以用this

class Bank {
    int money = 0; //預設一個變數叫money 寫在所有自訂義func的外面

    void Withdraw(int money){// 傳進來的參數也叫money
        System.out.println("存入金額"+money);
        System.out.println("目前帳戶餘額:" + (this.money +money ));
        // this.money會指向 最外面的那個money
        this.money += money ;
    }
}

若今天要寫在下方 class main中 你會發現下面的寫法是錯誤的

public class Main {
    public static void main(String[] args) {
        int age;
    }
    public static int year(int age){
        this.age = age
        return age+10;
    }
}

錯誤1 – 因為 this 只能用在非靜態方法中

而static表示了靜態

錯誤2 – int age 宣告的地方 應該要是所有自訂義function的最外層 1不是在其他function ( main )裡面

正確寫法

public class Main {
    int age; // 因為Main也是個類別 所以要寫在所有func的最外面
    
    int year(int age){
        this.age = age;
        return this.age+10;
    }
    
    public static void main(String[] args) {
        Main obj = new Main(); // 創建物件
        obj.age = 20;          // 設定 age
        System.out.println("Age after 10 years: " + obj.year(obj.age));
    }
}