緩く型付けされたオブジェクト (JavaScript など) として動作するクラス (または同じインターフェイスを実装するクラスのセット) を定義しようとしています。それらはあらゆる種類のデータを保持でき、それらに対する操作は基になる型に依存します。
私はそれを 3 つの異なる方法で動作させていますが、理想的な方法はありません。これらのテスト バージョンでは、文字列と整数のみが許可され、唯一の操作は追加です。整数を追加すると整数値の合計になり、文字列を追加すると文字列が連結され、整数を文字列に追加すると整数が文字列に変換され、文字列と連結されます。最終バージョンには、より多くの型 (Double、Array、新しいプロパティを動的に追加できる JavaScript のようなオブジェクト) とより多くの操作が含まれます。
方法 1:
public interface DynObject1 {
@Override public String toString();
public DynObject1 add(DynObject1 d);
public DynObject1 addTo(DynInteger1 d);
public DynObject1 addTo(DynString1 d);
}
public class DynInteger1 implements DynObject1 {
private int value;
public DynInteger1(int v) {
value = v;
}
@Override
public String toString() {
return Integer.toString(value);
}
public DynObject1 add(DynObject1 d) {
return d.addTo(this);
}
public DynObject1 addTo(DynInteger1 d) {
return new DynInteger1(d.value + value);
}
public DynObject1 addTo(DynString1 d)
{
return new DynString1(d.toString()+Integer.toString(value));
}
}
...DynString1 についても同様
方法 2: public interface DynObject2 { @Override public String toString(); public DynObject2 add(DynObject2 d); }
public class DynInteger2 implements DynObject2 {
private int value;
public DynInteger2(int v) {
value = v;
}
@Override
public String toString() {
return Integer.toString(value);
}
public DynObject2 add(DynObject2 d) {
Class c = d.getClass();
if(c==DynInteger2.class)
{
return new DynInteger2(value + ((DynInteger2)d).value);
}
else
{
return new DynString2(toString() + d.toString());
}
}
}
...DynString2 についても同様
方法 3:
public class DynObject3 {
private enum ObjectType {
Integer,
String
};
Object value;
ObjectType type;
public DynObject3(Integer v) {
value = v;
type = ObjectType.Integer;
}
public DynObject3(String v) {
value = v;
type = ObjectType.String;
}
@Override
public String toString() {
return value.toString();
}
public DynObject3 add(DynObject3 d)
{
if(type==ObjectType.Integer && d.type==ObjectType.Integer)
{
return new DynObject3(Integer.valueOf(((Integer)value).intValue()+((Integer)value).intValue()));
}
else
{
return new DynObject3(value.toString()+d.value.toString());
}
}
}
if-else ロジックを使用すると、型を格納する代わりに value.getClass()==Integer.class を使用できますが、より多くの型を使用すると、これを変更して switch ステートメントを使用し、Java では switch でクラスを使用できません。
とにかく...私の質問は、これを行うための最良の方法は何ですか?