5.5 JAVA
Java VS C++
Java
C++
Pure O.O language, 因為主程式都在 class 中
較不 pure
No pointer
有 pointer
Single Inheritance
Multiple Inheritance
利用 garbage collection , 不需有destructor
沒有 garbage collection , 需有destructor
interpret language, speed 較慢
compile language, speed 較快
Cross platform
沒有跨平台
安全性佳, 因為JVM (有類別驗證器)
安全性較差
support open source 較多
較少
Garbage Collection(垃圾回收): 指不要的 Mem. 會由系統來進行自動回收的機制 => 回收 programmer 不需介入, 所以不須 destructor
Note: java 中的 thread 的環境有較妥善的機制和方便 api 供 user 使用
Class 格式
1 2 3 4 5 6 class class_name { constructor -> object initial att -> 變數宣告 method -> function define };
Constructor (建構子)
和 C++ 概念相似
O.O 中所有物件皆需 “初始化” => 一定要呼叫 constructor
當 class 無 constructor, 系統會補上 預設建構子
Default constructor:
權限同 class
Parameter list 為空
Constructor code 為空
1 2 3 4 5 6 7 public class A { public A () {} // 自動補上 default constructor // public 1 // () 2 // {} 3 }
主程式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class Test { public static void main(string [] args) { ... //進入點 } } public class A { public static void main() // ()非主程式 { ... } } 1. compile error 2. runtime error 3. No error Ans: 2 出現 "main method not found"
配置物件 Mem.space => “new”
格式: class object = new class 建構子 (...欲傳入的參數);
Ex:
1 2 3 4 5 6 7 8 Person p = new Person(); // new 正式做 Memory allocation // Person() 呼叫 class Person 不帶參數的 constructor Person p; p.height = 180; // in C ,Yes // in Java , 尚未配置 Mem space
Note: 物件操作方式同 C++, object.att
or object.op
Inheritance 繼承
1 2 3 4 5 6 7 8 9 class A { } class B extends A { }
downcasting 向下轉型
upcasting 向上轉型
將父類別物件視為子類別型態
相反
有 risk, compiler 擋掉
沒有 risk
1 2 3 Person p = new Superman(); // superman upcasting Superman s = new Person(); // person downcasting Superman s = new Xman(); // X
Overriding
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Person { public void iam() { System.out.println("I am a Person"); } } class Superman extends Person { public void iam() { System.out.println("I am a Superman"); } }
注意:
method signature 方法簽章 要一樣
return type + method name + (parameter list)
Ex:
superclass: double getValue()… // compile error 多型會錯
subclass: string getValue()…
Ex2:
superclass: void print(int i)… 沒有 overriding 為 overloading, compile OK
subclass void print()…
Subclass 的存取權限要 ≥ superclass 的存取權限, 為避免多型有誤
Note: public > protected > private
this, super
概念同 C++, 但 Java 中 this, super 非 pointer , 其用法同一般物件, this/super.att/method
圖:
Ex:
Constructor 的進一步介紹 (constructor 的延伸)
constructor 不會被繼承
在 inheritance之下, subclass 的 constructor 第一行需呼叫 “super(…)” (若無, 系統會自動加上"super()" 呼叫 parent, 不帶任何參數的 constructor) => 呼叫父類別的建構子產生 parent object
處理的順序(初始化時)
1 2 3 4 5 6 7 8 9 10 11 12 class A { public A() {...} } class B extends A { public B() { super(); ... } }
1 2 3 4 5 6 7 8 9 10 11 12 13 public class A { public A(int a){} } public class B extends A { public B() // default constructor { super(); // 系統補上的, 找不到不帶參數的建構子 } } // Result: compile error
Summary:
No constructor => 補上 default constructor
若為 subclass 之 constructor 第一行無 “super(…)”, 自動補上 “super(…)” (不帶任何參數的)
Ex:
Java 的例外處理 (Exception Handler)
於 Java 中採用 try…catch…finally 來做例外處理
格式:
1 2 3 4 5 6 7 try { // 嘗試執行的動作 } catch (Exception e) { // 做例外捕捉後的 exception } finally { // 最後需執行的動作 }
說明:
try 一定存在, catch 跟 finally 至少需有1個
try 若遇到 Exception, 則之後的 statement 不做, 拋出 Exception object
catch 會捕捉 Exception, 並加以處理
try or catch 結束後, 會執行 finally block
若只有 try, finally , 當發生 exception 時, 會:
先執行 finally block
再將 Exception 往外拋
1 2 3 4 5 6 7 8 9 10 11 12 13 try { ... exception occurs; // 1 System.out.println("1"); } catch (Exception e) { // 2 System.out.println("2"); } finally { System.out.println("3"); } // Q1: output = ? 2, 3 // Q2: 拿掉 1, output = ? 1, 3 // Q3: 拿掉 2, output = ? 3, runtime exception
array 初始化
in O.O 所有物件皆需 初始化 (呼叫建構子)
in Java array 即為物件, 所以需初始化
不同型別的初始值
基本型別: boolean, char, byte, int, long, short, float, double
物件型別: “null”
Java 中的 array 宣告
type 陣列 name[] = new type [size];
ex: int a[] = new int[3];
ex1: double d() = new double[3];
主程式:
1 2 3 String s[] = new String[3]; s[s.length - 1] = "hello"; System.out.println("s[1]");
Note: 若為 “基本型別”, 且為 “區域變數”, 則:系統不會幫忙初始化, 需自行設預設值, 若無則處理時會有compile error
Ex:
static keyword
類別 -> 靜態, 物件 -> 動態
說明: static 修飾詞可用於 attribute, method 宣告中, 代表此 attribute, method 為 class 所有, 非 object 的
Note: data member 可分為:
attribute:
class variable (static)
instance variable (non-static)
method
class method (static)
instance method (non-static)
Ex:
1 2 3 4 5 6 7 class A { public static int x; public int y; } A a1 = new A(); A a2 = new A();
成大: 一公司有員工的類別, 有下列屬性, 何者適合宣告為 static:
姓名
手機
住址
配偶
CEO V
static 注意事項
static method 只能存取 static 的 attribute 及 method, 無法用 Non-static 之 attribute 及 method
1 2 3 4 5 6 7 8 9 10 // 先有類別, 才有物件 class A { public static int x; public int y; // non-static public static void count() { System.out.println(x+y); // y compile error } }
1 2 3 4 5 6 7 8 9 10 class A { public void get X() { } public static void get() { get x(); // compile error } }
static method 不可被 override (因為 static method 為靜態的, 故無法達多型(Dynamic Binding))之效)
final keyword
可用來修飾:
class: 代表此 class 不可再被繼承
ex:
父: final class A {}
子: calss B extends A{}
compile error
method: 此 method 不可被 override
ex:
superclass: public final void print() {}
subclass: public void print(){}
compile error, 因為 final 不能被 override
attribute: 代表此attribute 的值為 常數
ex:
public final int x = 10;.....x = 50;
compile error, 因為常數不能被更改
polymorphism in Java
Java 的多型不需有 “virtual” 的 keyword, 因為在 java 中所有的 method 皆具 virtual function 功能, 不需額外宣告, 亦即 method 皆可達 Dynamic Binding 之效
說明:
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 class Animal { public void walk() { System.out.println("An.walk"); } } class Person extends Animal { public void walk() { System.out.println("Person walk"); } } class Dog extends Animal { public void walk() { System.out.println("Dog walk"); } } /* Polymorphism: inheritance + overriding + upcasting 把子類別的物件, 向上看成父類別的型態 */
Note:
在 C++, 中做多型要有 virtual
在 java 中的 method 所有都是 virtual, 除了 static 的
應用:
Abstract method
Def: 當 method 沒有 implement 謂之 abstract method
Ex:
1 2 3 4 public abstract void walk() { // implement }
Abstract class
Def:
當 class 中具 ≥ 1 個 abstract method, 即需定義為 abstract class
abstract class 不能產生出實體(即無法 “new” 出 instance)
繼承 abstract class, 並將其 abstract method override 掉的謂之 concrete class
Ex1:
Ex2:
1 2 3 Animal a = new Animal(); // X 抽象類別不能 new Person p = new Person(); // O Animal a = new Person(); // O 實際上產生具象, Person 做 upcasting -> 準備做多型
1 2 3 4 5 6 7 8 9 10 11 12 13 abstract class Animal { public abstract void walk(); } // compile error class Person extends Animal // Solution1: 前方加上 abstract { // solution 2 public void walk() { System.out.println("Person walk"); } }
Note: 1, 2 擇一, 皆無時, 會有 compile error
用 1 不用 2 時, 代表 Person 為 abstract, 代表此層不會是最後一層
Sol: 既然不知道它該怎麼寫幹嘛定義? (第一個 abstract)
ANS: 拿掉就好, 但它如果定義出來, 他會具備規範的效果, 若定義走路是抽象, 若以後繼承我, 一定要把走路做完, 否則 compile 會提醒, 程式少漏洞
interface
通常是規格規範的動作 (根本不會產生物件, 所以也陪有 non-static 的問題)
格式:
1 2 3 4 5 6 7 8 interface name { public static final attribute_name; public abstract method signature; // public static or public abstract 可省略, 但系統會自動加上 }
方法全部都是抽象的, 就代表根本沒辦法實體化, 沒辦法產生物件, 幹嘛產生建構子, 建構子是用來做初始化的動作, 不會產生物件, 所以就不用有建構子了
Why interface?
利用 interface 讓 Java 模擬出 Multiple Inheritance
圖:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Person { } interface Flyer { public static void fly(); // 若只寫這樣也會過, 括號內連寫都沒寫, implement 是把它補起來, override 是重新定義 } class Superman extends Person implements Flyer // 介面可以實作很多個 { public void fly() { System.out.println("flying"); } }