私はのようなリストを使用していた場合、私は、思った全体の時間List<Thing> things = new ArrayList<>()
、このリスト内のすべての項目はタイプですThing
。昨日、私は他の方法を教えました。
私はそれがあるようにそれがある理由を以下のものと不思議を作成しました。
アン・インタフェース Thing
public interface Thing {
String getType();
String getName();
}
Aクラス ObjectA
public class ObjectA implements Thing {
private static final String TYPE = "Object A";
private String name;
public ObjectA(String name) {
this.name = name;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("ObjectA{");
sb.append("name='").append(name).append('\'');
sb.append('}');
return sb.toString();
}
@Override
public String getType() {
return TYPE;
}
@Override
public String getName() {
return name;
}
// equals and hashCode + getter and setter
}
Aクラス ObjectB
public class ObjectB implements Thing {
private static final String TYPE = "Object B";
private String name;
private int value1;
private String value2;
private boolean value3;
public ObjectB(String name, int value1, String value2, boolean value3) {
this.name = name;
this.value1 = value1;
this.value2 = value2;
this.value3 = value3;
}
@Override
public String getType() {
return TYPE;
}
@Override
public String getName() {
return name;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("ObjectB{");
sb.append("name='").append(name).append('\'');
sb.append(", value1=").append(value1);
sb.append(", value2='").append(value2).append('\'');
sb.append(", value3=").append(value3);
sb.append('}');
return sb.toString();
}
// equals and hashCode + getter and setter
}
main
方法
public static void main(String[] args) {
final List<Thing> things = new ArrayList<>();
final ObjectA objA = new ObjectA("Thing 1");
final ObjectB objB = new ObjectB("Thing 2", 123, "extra", true);
things.add(objA);
things.add(objB);
// The List doesn't contain Thing entities, it contains ObjectA and ObjectB entities
System.out.println(things);
for(final Thing thing : things) {
if (thing instanceof ObjectA) {
System.out.println("Found Object A: " + thing);
final ObjectA object = (ObjectA) thing;
}
if (thing instanceof ObjectB) {
System.out.println("Found Object B: " + thing);
}
}
}
このメソッドの出力は次のようになります。
[ObjectA{name='Thing 1'}, ObjectB{name='Thing 2', value1=123, value2='extra', value3=true}]
私は仮定ので、私はしましたObjectA
エンティティとObjectB
、私の中でエンティティをList<Thing>
。
質問:できる人は、この動作を説明するリンク(または検索に使用することができ、いくつかのキーワードを)、提供、または私にそれを説明できますか?
追加の質問:私はこれをフィルタリングするために始めたList<Thing>
とinstanceof
私はinstanceofは読んだことがあると鋳造が悪い習慣(例えばダメモデル設計)です。すべてのタイプのために、このリストをフィルタリングする「良い」方法ですされるObjectA
だけで、これらはいくつかの操作をオブジェクトに対して実行するには?
誰かがこの動作を説明する、または私にそれを説明することができますリンク(または検索に使用することができますいくつかのキーワード)を、提供することはできますか?
この動作は、「多型」と呼ばれています。基本的に、以降ObjectA
およびObjectB
器具Thing
の、例ObjectA
とObjectB
同様に使用することができるThing
オブジェクト。あなたのコードでは、あなたは含めることができ、リストに追加しThing
たオブジェクトを。
これらのオブジェクトは現在、(コンパイル時)型であっても、どのように注意Thing
実行時には、彼らはまだ彼らが何であるかを知っています。あなたは呼び出すとtoString
、それぞれのオーバーライドされ、それらの上toString
のメソッドObjectA
とObjectB
呼ばれます。それはあるかのようであるThing
「モーフ」へのObjectA
かObjectB
。
これらは、いくつかの操作をオブジェクトだけで実行するObjectAに、すべてのタイプのために、このリストをフィルタリングする「良い」の方法はされますか?
あなたが別のものをしたい場合は、オブジェクトがあるかどうかによってので、人々は、これは悪い習慣であると言う理由はあるObjectA
かObjectB
、なぜあなたがそれらを実装作った、Thing
とのリスト作りThing
、それらを格納するの?あなただけ使用することもできますList<Object>
。使用しての本当の利点は、List<Thing>
あなたがいることで避けるリストで作業しているとき、実際のオブジェクトがそこにあるかを知ること。あなたが知っているすべては、リスト内の物事が実装することでThing
、あなたがで宣言されたメソッドを呼び出すことができますThing
。
あなたは二つのタイプを分離するために、リストをフィルタリングする必要があるのであれば、あなただけの最初の場所でそれらを格納するために2つのリストを作成している可能性があります。一つObjectA
とに1つObjectB
。明らかに、このリストはどこか(外部ライブラリなど)から来ている場合は特に、常に可能ではありません。その場合は、あなたの現在のコードは大丈夫です。