สำคัญมาก กฎ Exception ใน Overriding คล้ายกับ Try-Catch: Subclass เมธอดอาจโยน Exception ชนิดเดียวกัน หรือ Subtype (ลูก) เท่านั้น ห้ามโยน Supertype (พ่อแม่)
กฎหลัก (Overriding & Throws)
- Override เมธอดที่โยน Checked Exception -> โยน Exception ชนิดเดียวกัน ได้
- โยน Exception ที่เป็น Subclass (Subtype) ของ Exception เดิม ได้
- ห้ามโยน Supertype (Parent Class) ของ Exception เดิม
- Override โดย ไม่โยน Exception เลย ก็ได้
ตัวอย่าง: โยน Subtype (ถูกต้อง)
class Demo {
public void sample() throws ArrayIndexOutOfBoundsException {
System.out.println("Demo class");
}
}
class SuperTest extends Demo {
// IndexOutOfBoundsException เป็น Parent ของ ArrayIndexOutOfBoundsException -> ผิด!
// แต่อยู่ใน Hierarchy เดียวกัน ลองดูตัวอย่างถูกต้องด้านล่าง
public void sample() throws IndexOutOfBoundsException { // Error: Supertype
System.out.println("SuperTest class");
}
}
ตัวอย่างข้างต้น ผิด เพราะ IndexOutOfBoundsException เป็น Supertype ของ ArrayIndexOutOfBoundsException
ตัวอย่างที่ถูกต้อง: โยน Subtype
import java.io.IOException;
import java.io.EOFException; // EOFException extends IOException
class Demo {
public void sample() throws IOException {
System.out.println("Demo class throws IOException");
}
}
class SuperTest extends Demo {
// EOFException เป็น Subtype ของ IOException -> ถูกต้อง
public void sample() throws EOFException {
System.out.println("SuperTest throws EOFException (subtype)");
}
}
public class Test {
public static void main(String args[]) {
Demo obj = new SuperTest();
try {
obj.sample();
} catch (IOException ex) { // จับ IOException ได้ (Parent)
System.out.println("Caught IOException");
}
}
}
ผลลัพธ์
SuperTest throws EOFException (subtype) Caught IOException
ตัวอย่างที่ Error: โยน Supertype
class Demo {
public void sample() throws EOFException { // Specific
System.out.println("Demo throws EOFException");
}
}
class SuperTest extends Demo {
// IOException เป็น Supertype ของ EOFException -> Error!
public void sample() throws IOException {
System.out.println("SuperTest throws IOException");
}
}
Compile Error
Test.java:12: error: sample() in SuperTest cannot override sample() in Demo
public void sample() throws IOException {
^
overridden method does not throw IOException
เหตุผล
Code เรียกผ่าน Demo obj = new SuperTest() คาดหวังแค่ EOFException แต่ Subclass โยน IOException ที่กว้างกว่า -> Caller ไม่ Catch ได้ -> Runtime Crash Java จึงบังคับที่ Compile-time
สรุป
Hierarchy ของ Exception สำคัญมาก: Override ได้แค่ Same หรือ Narrower (Subtype) เท่านั้น สอดคล้องกับ Liskov Substitution Principle