Fruit型の変数fにはFruitのインスタンスが入っているかもしれないし、サブクラスのOrangeのインスタンスが入っている可能性もあります。ですが、実行時にその変数の実体が何のクラスのインスタンスかというのは基本的に気にしない(させてはいけない)のがポリモーフィズムの考え方です。FruitクラスのfooメソッドはExceptionを投げる可能性があると宣言しているので、try-catchで処理するかメソッドでthrows宣言する必要があります。
またこの仕組みのため、サブクラスでメソッドをオーバーライドする際は、スロー宣言する例外の型を狭める(サブクラス型で宣言する、もしくは宣言をなくす)ことはできますが、広げる(スーパークラス型で宣言する、継承関係がない他の型を宣言する)ことはできません。
java
1class A {
2 void hoge() throws IOException {
3 throw new IOException();
4 }
5}
6
7class B extends A {
8 // FileNotFoundExceptionはIOExceptionのサブクラス
9 @Override
10 void hoge() throws FileNotFoundException {
11 throw new FileNotFoundException();
12 }
13}
14
15class C extends A {
16 @Override
17 void hoge() throws Exception { // コンパイルエラー
18 throw new Exception();
19 }
20}
上記のようなクラスを例に考えます。本来ならコメントに書いたようにCクラスでコンパイルエラーになりますが、仮にこのコンパイルが通ったとしましょう。
java
1try {
2 A a = new B();
3 a.hoge();
4} catch (IOException e) {
5 e.printStackTrace();
6}
A型のメソッドhogeはIOExceptionをスローする可能性があるため、それを処理するためのtry-catchを書くことになります。このコードでは実際にはBクラスのインスタンスが入るわけですが、そのメソッドhogeはFileNotFoundExceptionをスローします。ですが、これはIOExceptionのサブクラスなので、問題なくこのcatch節でキャッチできます。hogeが何もスローしないとしても、catchに到達しないというだけで問題はありません。
java
1try {
2 A a = new C();
3 a.hoge();
4} catch (IOException e) {
5 e.printStackTrace();
6}
ところが、A型の変数に問題のCクラスが入った場合、困るのです。このhogeメソッドからスローされる例外はExceptionなのですが、これはこのcatch節でキャッチできません。そのため、メソッドの例外スロー宣言は広げられないようになっているのです。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/09/20 10:00