Có, rất quan trọng. Quy tắc ném exception khi override:
- Phương thức con ném cùng exception hoặc sub-type (con) của exception ở phương thức cha.
- Phương thức con KHÔNG được ném super-type (cha) của exception ở phương thức cha.
- Phương thức con có thể không ném exception nào (như bài trước).
Ví dụ hợp lệ: Sub-type exception
class Demo {
public void sample() throws ArrayIndexOutOfBoundsException {
System.out.println("Demo class");
}
}
class SuperTest extends Demo {
// IndexOutOfBoundsException là CHA của ArrayIndexOutOfBoundsException -> SAI
// Nhưng ví dụ này ném IndexOutOfBoundsException (cha) -> Sẽ lỗi!
// Sửa: ném ArrayIndexOutOfBoundsException hoặc sub-type
public void sample() throws ArrayIndexOutOfBoundsException { // OK: cùng kiểu
System.out.println("SuperTest class");
}
}
public class Test extends SuperTest {
public static void main(String args[]) {
Demo obj = new SuperTest();
try {
obj.sample();
} catch (ArrayIndexOutOfBoundsException ex) {
System.out.println("Exception caught");
}
}
}
Ví dụ SAI: Ném super-type
import java.io.IOException;
import java.io.EOFException;
class Demo {
public void sample() throws IOException { // IOException là CHA của EOFException
System.out.println("Demo class");
}
}
class SuperTest extends Demo {
public void sample() throws EOFException { // OK: EOFException là CON của IOException
System.out.println("SuperTest class");
}
}
public class Test extends SuperTest {
public static void main(String args[]) {
Demo obj = new SuperTest();
try {
obj.sample();
} catch (EOFException ex) { // Bắt EOFException
System.out.println("Exception");
}
}
}
Kết quả: OK vì EOFException extends IOException.
Ví dụ SAI ngược lại
class Demo {
public void sample() throws EOFException { // Con
System.out.println("Demo");
}
}
class SuperTest extends Demo {
public void sample() throws IOException { // SAI: Cha của EOFException
System.out.println("SuperTest");
}
}
Test.java: error: sample() in SuperTest cannot override sample() in Demo overridden method does not throw IOException
Tóm tắt: Exception ném ra khi override phải tuân theo quy tắc covariant (cùng kiểu hoặc cụ thể hơn - sub-type). Điều này đảm bảo code gọi phương thức cha vẫn bắt được exception phù hợp.