正在載入...
請稍候
封面
示例歌曲名稱
示例藝術家
0:00 / 0:00

播放列表

第十章:自訂類別與方法

未分類
4.2k 字

什麼是「自訂類別」

在 Java 中,我們可以自己定義一個類別(class)來描述某個事物的屬性(成員變數)和行為(方法)。這就叫做自訂類別,是物件導向的基礎。



類別 vs 物件

名稱 是什麼? 範例
類別(Class) 藍圖 class Student {}
物件(Object) 真正的實體 Student s1 = new Student();



如何定義一個類別

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Student {
// 成員變數(欄位 / 屬性)
String name;
int age;

// 方法(行為)
void sayHi() {
System.out.println("Hi! 我是 " + name);
}
}

public class Main {
public static void main(String[] args) {
Student s1 = new Student(); // 建立物件
s1.name = "小明";
s1.age = 18;
s1.sayHi();
}
}

輸出結果:

1
Hi! 我是 小明



記憶體說明(Stack vs Heap)

1
Student s = new Student();
區域 儲存什麼
Stack 變數 s,存放記憶體地址
Heap 實際的 Student 物件(name, age…)



建構子 Constructor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Student {
String name;
int age;

Student(String n, int a) {
name = n;
age = a;
}

void sayHi() {
System.out.println("我是 " + name + ",今年 " + age + " 歲");
}
}

public class Main {
public static void main(String[] args) {
Student s = new Student("小華", 17);
s.sayHi();
}
}

Student 類別:

  • 定義了兩個屬性:nameage
  • 建構子接收姓名和年齡來初始化物件
  • sayHi() 方法用來自我介紹

Main 類別:

  • 建立一個名為”小華”、17歲的 Student 物件
  • 呼叫 sayHi() 方法

執行結果

我是 小華,今年 17 歲

關鍵概念

  • 建構子:Student(String n, int a) 在建立物件時自動執行
  • 物件建立:new Student("小華", 17) 建立實體
  • 方法呼叫:s.sayHi() 執行物件的行為



this 關鍵字

this 代表「當前物件本身」,用來區分參數和屬性。

問題:參數和屬性同名怎麼辦

1
2
3
4
5
6
7
8
9
class Student {
String name;
int age;

Student(String name, int age) {
name = name; // ❌ 錯誤!都是指參數
age = age; // ❌ 錯誤!都是指參數
}
}

問題:Java 分不清楚你要的是「屬性」還是「參數」,預設會使用「參數」。

解決方案:使用 this

1
2
3
4
5
6
7
8
9
class Student {
String name;
int age;

Student(String name, int age) {
this.name = name; // ✅ 屬性 = 參數
this.age = age; // ✅ 屬性 = 參數
}
}

解釋

  • this.name = 物件的屬性
  • name = 建構子的參數



this 的三種用法

1. 區分屬性和參數(最常用)

1
2
3
public Student(String name) {
this.name = name;
}

2. 呼叫其他方法

1
2
3
public void introduce() {
this.printName(); // 可省略 this
}

3. 呼叫其他建構子

1
2
3
4
5
6
7
8
public Student(String name) {
this(name, 18); // 呼叫另一個建構子
}

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

完整範例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Student {
String name;
int age;

// 建構子
public Student(String name, int age) {
this.name = name; // 區分屬性和參數
this.age = age;
}

// 方法
public void introduce() {
System.out.println("我是 " + this.name + "," + this.age + " 歲");
}
}

重點

  • this = 當前物件
  • 主要用來解決「同名衝突」
  • 讓程式碼更清楚易讀



常見錯誤觀念澄清

錯誤觀念 正確觀念
物件等於類別 ❌ 物件是由類別產生的實體
類別不能有同名方法 ❌ 可以「多載 overload」
屬性不用初始化 ❌ 建議在建構子中初始化
this 是 Java 保留變數 ✅ 是參考「自己的」關鍵字



重點整理

  • 自訂類別就是自創一種資料型別(描述屬性+行為)
  • 類別是藍圖,物件是實體(用 new 建立)
  • 資料放在 Heap,變數位址放在 Stack
  • 建構子在建立物件時自動執行
  • this 代表目前物件本身,常用來解決命名衝突



什麼是方法

Java 中,「方法」是物件的功能、動作、行為



方法基本語法

1
2
3
回傳型別 方法名稱(參數列表) {
// 方法內容
}

範例:

1
2
3
void sayHi() {
System.out.println("Hi!");
}



有參數的方法

1
2
3
void sayHiTo(String name) {
System.out.println("Hi, " + name);
}



有回傳值的方法

1
2
3
int add(int a, int b) {
return a + b;
}



有參數 + 有回傳值

1
2
3
double bmi(double w, double h) {
return w / (h * h);
}



方法分類

類型 說明 範例
無參數無回傳值 執行某件事但不給資料 void sayHi()
有參數無回傳值 根據參數做事但不回資料 void sayHiTo(String name)
無參數有回傳值 做事後給你一個值 int getAge()
有參數有回傳值 根據參數做事並回傳結果 double bmi(double w, h)



物件呼叫方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Student {
String name;
int age;

Student(String n, int a) {
name = n;
age = a;
}

void sayHi() {
System.out.println("我是 " + name);
}
}

public class Main {
public static void main(String[] args) {
Student s = new Student("小華", 17);
s.sayHi();
}
}



return 是什麼

return 把結果「丟回去」給呼叫的人。

1
2
3
4
5
6
7
8
9
10
public class Main {
public static void main(String[] args) {
int result = doubleNum(5); // 呼叫方法
System.out.println(result); // 輸出結果
}

static int doubleNum(int x) {
return x * 2; // 回傳值
}
}



特別注意

有明確定義建構式時,不會自動產生預設空白建構式,所以需要手動定義預設建構式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// Point.java 所屬封包名稱「math.geometry」
package math.geometry;

public class Point {
public int x;
public int y;

// 建構式1:只接受x參數
public Point(int x) {
this.x = x;
this.y = 10;
}

// 建構式2:接受x和y參數
public Point(int x, int y) {
this.x = x;
this.y = y;
}

// 預設建構式(無參數)
public Point() {
this.x = 0;
this.y = 0;
}

// 顯示點座標的方法
public void render() {
System.out.println(this.x + ", " + this.y);
}
}

// App.java 為主程式
// import math.geometry.Point;

class App {
public static void main(String[] args) {
// 使用第一個建構式(只傳入x值)
Point p1 = new Point(6);
p1.render(); // 印出 6, 10

// 使用第二個建構式(傳入x和y值)
Point p2 = new Point(3, 4);
p2.render(); // 印出 3, 4

// 錯誤:有明確定義建構式時
// 不會自動產生預設空白建構式
// 所以需要手動定義預設建構式
Point p3 = new Point();
p3.render(); // 印出 0, 0
}
}