我有一個非常簡單的包裝類,它存儲任何類及其類型的對象。現在我想要檢索該對象並想對其執行一些操作。在Java中動態類型轉換對象
這是我目前使用我的代碼,一個簡短的演示,但它變得太長
Literal a = new Literal(new Complex(12, 0));
Literal b = new Literal(new Matrix(n, m));
Literal c = new Literal(new Variable("x"));
Literal d = new Literal(new Constant("y", 2.25));
Literal e = new Literal(new Real(2.5));
if (a.getType() == Literal.Type.COMPLEX)
{
Complex w = (Complex)a.getLiteral();
//Doing something
}
else if (a.getType() == Literal.Type.Matrix)
{
Matrix w = (Matrix)a.getLiteral();
//Doing something
}
else if (a.getType() == Literal.Type.Variable)
{
Variable w = (Variable)a.getLiteral();
//Doing something
}
else if (a.getType() == Literal.Type.Constant)
{
Constant w = (Constant)a.getLiteral();
//Doing something
}
else if (a.getType() == Literal.Type.Real)
{
Real w = (Real)a.getLiteral();
//Doing something
}
/* Same goes for all other Objects
* and I need to do this at least in
* 50 different places*/
三種解決方案來到我的腦海從兩者沒有在這種情況下工作
使
Literal
基類和其他所有其他孩子,但Literal
並沒有其子女將擁有的所有方法,會有很多孩子。使
Literal
是一個泛型類,但我想要存儲的類型是可變的,所以我需要複製它們,Java不允許調用泛型的任何方法。這是行得通的,但它增加了很難找到的錯誤的概率。
這是迄今爲止我嘗試:
import org.apache.commons.math3.linear.BlockRealMatrix;
public class Literal<T>
{
private final Object literal;
/*
* public enum Type
* {
* COMPLEX,
* VARIABLE,
* REAL,
* CONSTANT,
* MATRIX
* }
* private final Type type;
* */
public Literal(Complex c)//Complex class is mutable so make copy of passed object
{
this.literal = new Complex(c);
//this.type = Type.COMPLEX;
}
public Literal(Real d)//Real is not mutable so no need to make copy
{
this.literal = d;
//this.type = Type.REAL;
}
public Literal(BlockRealMatrix realMatrix)//BlockRealMatrix class is mutable so make copy of passed object
{
int m = realMatrix.getData().length;
int n = realMatrix.getData()[0].length;
BlockRealMatrix mat = new BlockRealMatrix(m, n);
for (int i = 0; i < m; i++)mat.setRow(i, realMatrix.getRow(i));
this.literal = mat;
//this.type = Type.MATRIX;
}
public T get()
{
return (T)this.literal;
}
/*
public Literal.Type getType()
{
return this.type;
}
*/
@Override
public String toString()
{
return this.literal.toString();
}
}
在過去的方法可能錯誤是:
package com.kmstudios.evaluator;
public class Main
{
public static void main(String[] args)
{
Literal<Real> a = new Literal<>(new Complex2(25, 36));//Accidently passed reference of Real instead of Complex
Literal<Complex2> b = new Literal<>(new Complex2(50, 36));
Literal<Complex2> c = new Literal<>(a.get().multiply(b.get()));
System.out.println(c.toString());//Expecting for Complex to print
}
}
class Real
{
private final Double d;
public Real(double d)
{
this.d = d;
}
public Real multiply(Real other)
{
return new Real(this.d * other.d);
}
public final double get()
{
return this.d;
}
@Override
public String toString()
{
return Double.toString(this.d);
}
}
class Complex2 extends Real
{
private double imaginary;
public Complex2(double real, double imaginary)
{
super(real);
this.imaginary = imaginary;
}
public Complex2 multiply(Complex2 o)
{
return new Complex2(this.get() * o.get() - this.imaginary * o.imaginary, this.get() * o.imaginary + this.imaginary * o.get());
}
public Complex2 multiply(double other)
{
return new Complex2(this.get() * other, this.imaginary * other);
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder("");
builder.append(this.get());
if (this.imaginary >= 0.0)builder.append("+");
builder.append(this.imaginary);
return builder.toString();
}
}
我已經注意到這一個,但可能有更多的錯誤。我應該重新考慮我的 數據結構嗎?
我想知道是否有任何簡單,不易出錯,高效和簡短的方法來做到這一點。
*難以發現的錯誤*後[MCVE(http://stackoverflow.com/help/mcve) –
這裏是最後的4行代碼的問題? –
@RomanC我添加了MCVE –