Java 自學筆記 02 - OOP

Java OOP

Java 是一個物件導向的程式語言,重點在於如何定義物件之間的互動,Object Oriented Programming (OOP) 的三大特性分別是: Encapsulation (封裝)Inheritance (繼承)Polymorphism (多型)

Encapsulation (封裝)

所謂封裝(Encapsulation),是指class A的設計者可以指定其他的class能否存取A的某個member。

Access Modifier

類別中每個 member 的權限都是分開控制的,存取範圍的大小是public > protected > package > private。

  • private: 只有A自己才可以存取,使用keyword private
  • package (default): 只有和A同一個package的class才可以存取,沒有相對應的keyword
  • protected: 只有同一個package或是A的子類別才可以存取,使用keyword protected
  • public: 所有的class都可以存取,使用keyword public

Package

對應到資料夾名稱,不同層的資料夾視為不同封包:

1
2
package math;
package math.geometry;

要使用封包內的類別:

1
2
import math.BasicMath;
import math.geometry.*;

Inheritance (繼承)

Java使用關鍵字extends來表達繼承,若class宣告時沒有指定extends,則Java會自動extends java.lang.Object

1
2
3
4
5
6
7
8
9
10
public class Animal {
public String moveMethod() {
return "Unspecified";
}
}
public class Bird extends Animal {
public String moveMethod() {
return "Fly";
}
}

Override (覆寫)

子類別重新定義它所能看到的父類別中的 method (如 public、protected,如果子類別和父類別在同一個 package 裡,則沒有修飾字的method也可以),稱為override。

  • 如果子類別看不到父類別的方法 (如父類別的 private 方法,或子父類別不在同一個 package 而子類別定義了父類別內的 package method),則就算定義了同樣的 method 也不是override
  • 重複定義 static method 也不算 override
  • 子類別不可縮小父類別方法的存取範圍
1
2
3
4
5
6
7
public class C2 {
public void a() {}
}
public class C1 extends C2 {
protected void a() { // Compile Error,不得縮小存取範圍
}
}

final 修飾字

final 除可用來修飾變數外,也可放在class和object method前面:

1
2
3
4
5
public final class FinalClass {
public final void finalMethod() {
}
}

final放在class前面表示class不可被繼承,放在object method表示不可被Override。

Polymorphism (多形)

UpCasting (向上轉型)

子類別可以向上相容於父類別,舉例來說,Bird 是一種 Animal,所以可以順利向上轉型。

1
2
3
Animal a;
Bird b;
a = b; // upcasting, Bird is a kind of Animal

DownCasting (向下轉型)

相反的,父類別並不能像下相容子類別,因為 Animal 並不一定都是 Bird,如果要向下轉型必須要強制casting。

1
2
3
4
5
Animal a = new Bird(); // upcasting
Bird b;
b = (Bird)a; // downcasting, compile correct
if (a instanceof Bird) { // true
}
  • InheritanceExample.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class InheritanceExample {
public static void main(String[] argv) {
Animal a1, a2, a3, a4;
Bird b;
Dog d;
Fish f;
a2 = a1 = new Animal();
b = new Bird();
d = new Dog();
f = new Fish();
System.out.println(a1.moveMethod());
System.out.println(b.moveMethod());
System.out.println(d.moveMethod());
System.out.println(f.moveMethod());
a1 = b; // Correct, we call this upcasting
b = a1; // Compile Error, type not compatible
b = (Bird)a1; // downcasting, Compile Correct
a2 = b; // Correct,we call this upcasting
d = a2; // Compile Error, type not compatible
d = (Dog)a2; // Compile Correct, but runtime error
}
}

instanceof 關鍵字

用來判斷某 reference 所指到的物件與類別是否相容 (including upcasting):

1
2
3
4
5
Object ref;
ref = new Bird();
if (ref instanceof Animal) { // correct
System.out.println("ref is currently pointing to an Animal Object.");
}

Virtual Function(虛擬函數)

當父類別 reference 到子類別的 object,ex: Animal a = new Bird(),如果子類別 override 父類別的 method,java 會呼叫子類別的方法,也就是 Virtual Function,(如果是呼叫父類別的方法就是 Non-Virtual Function)。

1
2
3
4
5
6
7
8
9
public class InheritanceExample {
public static void main(String[] argv) {
Animal a1;
a1 = new Animal();
System.out.println(a1.moveMethod()); // print out "Unspecified"
a1 = new Bird(); // polymorphism
System.out.println(a1.moveMethod()); // print out "Fly"
}
}

要注意 override 的範圍,只有被 override 的 method 才會呼叫 virtual function,舉例來說,static method 、private method 不能被 override,所以也不會有 virtual function。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Animal {
private String moveMethod() {
return "Unspecified";
}
public static void main(String[] argv) {
Animal a1;
a1 = new Bird();
System.out.println(a1.moveMethod()); // print out "Unspecified"
}
}
class Bird extends Animal {
// this is not override because Bird can't see Animal's moveMethod
public String moveMethod() {
return "Fly";
}
}

參考資料

https://programming.im.ncnu.edu.tw/J_index.html