Java Enumマルチステート
詳細
Enum多態、私は間違っていませんが、Enumは継承されてはいけません.他の人から継承されてはいけません.ただインタフェースを実現することができます.多態とは何ですか.しかし、まず「現象」を見てみましょう.
Javaコード
以上は簡単なenumですが、それについて補足します.Fruitはjava.lang.Enumのサブクラスです.正確には、Enumのサブクラスです.ここには継承関係が現れていますが、この継承はコンパイラが手伝ってくれたので、明示的にはできません.信じないならエンムの引用でAPPLEを指してみてもいいです.きっと大丈夫です.もうやってみません.これをより直感的に説明するために、Fruitの逆コンパイル結果を見てみましょう.
これらの行に注意してください.
JDK Enumの実現は、Effective Javaで提案されているTypeSafeEnumモードを踏襲したにすぎず、コンパイラやJVMなどより下位レベルでのサポートにすぎないようです.ここまで、少なくともFruitとEnumの継承関係を説明したが、問題は、今はFruitから子供を派遣し続けることができないのに、どこからの多態なのかということだ.もっとコードを書きましょう.
このうち、OrangeだけがOveride test()メソッドを持たない.メイン関数で呼び出します.
出力結果:
参照
I am an apple. I am a pear. I am a peach. I am a fruit.
testメソッドを再定義したAPPLE,PEAR,PEACHは親から継承されたデフォルトの動作を上書きし,testメソッドを新たに定義しないORANGEは親の動作を踏襲し,多態性がここで示されている.では、私たちはさっきFruitの反コンパイル結果を見たことがあるのに、Fruitから新しいクラスが継承されていないのを見たことがありますが、これらの多態行為はどこから出てきたのでしょうか.それが「多態」だと言うのは正しいのだろうか.実は、Fruitクラスはこの時点で微妙な変化が発生しており、すべてJDKのEnumの実現に関係しています.コンパイル結果ディレクトリの下を見てみましょう.
どうしてFruit.classのほかに、内部クラスのようなclassファイルがいくつか増えたのですか?ここを見て少し手がかりがあるかもしれませんが、この時に反コンパイルの結果を見て、何をしているのか見てみましょう.
Enum多態、私は間違っていませんが、Enumは継承されてはいけません.他の人から継承されてはいけません.ただインタフェースを実現することができます.多態とは何ですか.しかし、まず「現象」を見てみましょう.
Javaコード
public enum Fruit {
APPLE, PEAR, PEACH, ORANGE;
}
以上は簡単なenumですが、それについて補足します.Fruitはjava.lang.Enumのサブクラスです.正確には、Enumのサブクラスです.ここには継承関係が現れていますが、この継承はコンパイラが手伝ってくれたので、明示的にはできません.信じないならエンムの引用でAPPLEを指してみてもいいです.きっと大丈夫です.もうやってみません.これをより直感的に説明するために、Fruitの逆コンパイル結果を見てみましょう.
package test;
public final class Fruit extends Enum {
private Fruit(String s, int i) {
super(s, i);
}
public static Fruit[] values() {
Fruit afruit[];
int i;
Fruit afruit1[];
System.arraycopy(afruit = ENUM$VALUES, 0,
afruit1 = new Fruit[i = afruit.length], 0, i);
return afruit1;
}
public static Fruit valueOf(String s) {
return (Fruit) Enum.valueOf(test / Fruit, s);
}
public static final Fruit APPLE;
public static final Fruit PEAR;
public static final Fruit PEACH;
public static final Fruit ORANGE;
private static final Fruit ENUM$VALUES[];
static {
APPLE = new Fruit("APPLE", 0);
PEAR = new Fruit("PEAR", 1);
PEACH = new Fruit("PEACH", 2);
ORANGE = new Fruit("ORANGE", 3);
ENUM$VALUES = (new Fruit[] { APPLE, PEAR, PEACH, ORANGE });
}
}
これらの行に注意してください.
public static final Fruit APPLE;
public static final Fruit PEAR;
public static final Fruit PEACH;
public static final Fruit ORANGE;
JDK Enumの実現は、Effective Javaで提案されているTypeSafeEnumモードを踏襲したにすぎず、コンパイラやJVMなどより下位レベルでのサポートにすぎないようです.ここまで、少なくともFruitとEnumの継承関係を説明したが、問題は、今はFruitから子供を派遣し続けることができないのに、どこからの多態なのかということだ.もっとコードを書きましょう.
public enum Fruit {
APPLE {
public void test() {
System.out.println("I am an apple.");
}
},
PEAR {
public void test() {
System.out.println("I am a pear.");
}
},
PEACH {
public void test() {
System.out.println("I am a peach.");
}
},
ORANGE;
public void test() {
System.out.println("I am a fruit.");
}
}
public enum Fruit {
APPLE {
public void test() {
System.out.println("I am an apple.");
}
},
PEAR {
public void test() {
System.out.println("I am a pear.");
}
},
PEACH {
public void test() {
System.out.println("I am a peach.");
}
},
ORANGE;
public void test() {
System.out.println("I am a fruit.");
}
}
このうち、OrangeだけがOveride test()メソッドを持たない.メイン関数で呼び出します.
public static void main(String[] args) {
Fruit.APPLE.test();
Fruit.PEAR.test();
Fruit.PEACH.test();
Fruit.ORANGE.test();
} public static void main(String[] args) {
Fruit.APPLE.test();
Fruit.PEAR.test();
Fruit.PEACH.test();
Fruit.ORANGE.test();
}
出力結果:
参照
I am an apple. I am a pear. I am a peach. I am a fruit.
testメソッドを再定義したAPPLE,PEAR,PEACHは親から継承されたデフォルトの動作を上書きし,testメソッドを新たに定義しないORANGEは親の動作を踏襲し,多態性がここで示されている.では、私たちはさっきFruitの反コンパイル結果を見たことがあるのに、Fruitから新しいクラスが継承されていないのを見たことがありますが、これらの多態行為はどこから出てきたのでしょうか.それが「多態」だと言うのは正しいのだろうか.実は、Fruitクラスはこの時点で微妙な変化が発生しており、すべてJDKのEnumの実現に関係しています.コンパイル結果ディレクトリの下を見てみましょう.
どうしてFruit.classのほかに、内部クラスのようなclassファイルがいくつか増えたのですか?ここを見て少し手がかりがあるかもしれませんが、この時に反コンパイルの結果を見て、何をしているのか見てみましょう.