各種インナークラスに付けられる修飾子を一生覚えられません。
ので、理由とセットで覚えることにします。
出展:徹底攻略 Java SE11 Gold 問題集 p.26
public |
protected |
private |
abstract |
final |
static |
|
---|---|---|---|---|---|---|
インナークラス | 〇 | 〇 | 〇 | 〇 | 〇 | × |
staticインナークラス | 〇 | 〇 | 〇 | 〇 | 〇 | 〇 |
ローカルクラス | × | × | × | 〇 | 〇 | × |
匿名クラス | × | × | × | × | × | × |
ポイントとなるのは2点でしょうか:
- インナークラスの
static
が×なのはなぜ? - ローカルクラスの
abstract
とfinal
が〇なのはなぜ?
ここさえおさえておけばなんとかなりそうな表してますよね。
1. なんでインナークラスのstatic
が
なの?
インナークラスは定義上、外部クラスのインスタンスに紐づいている必要があります。ゆえに、外部クラスのインスタンスに依存しないとするstatic
なインナークラスは存在し得ません。よって、×。
static
を付けた瞬間、そのクラスは「インナークラス」ではなく「staticインナークラス」という別物と見なされます。
なんだかとんちみたいでムカつきますね。○なのか×なのかハッキリせえよ。
2. なんでローカルクラスのabstract
とfinal
だけが
なの?
1. public
, protected
, private
ローカルクラスのスコープは限定的で、他のクラスからアクセスされないからそもそも不要。よって、×。
2. static
ローカルクラスは外部クラスのインスタンスやスコープ内のローカル変数にアクセスすることを前提として設計されており、意図に反する。よって、×。
3. ここからが問題:abstract
とfinal
が〇なのはなぜ?
-
abstract
ローカルクラスが直接的に利用されるのではなく、拡張や具体的な実装がスコープ内で行われることを示せるので、〇。 -
final
ローカルクラスの振る舞いを完全に固定し、匿名クラスでのオーバーライドとかを防いだり出来るので、〇。
public class Outer {
public void myMethod() {
// ローカルクラス
abstract class AbstractLocalClass {
abstract void display();
}
// 匿名クラス
AbstractLocalClass local = new AbstractLocalClass() {
@Override
void display() {
System.out.println("Anonymous class implementing abstract local class.");
}
};
local.display();
}
}
正直、使う機会を全く想像できませんが、頭の片隅にでも置いておこうと思います。
まとめ
つべこべ言わず覚えます。