避免Java中数据类的动态类型转换和继承



我有3个数据类

@Data
class A
{
private int a;
}
@Data
class B extends A
{
private int b;
}
@Data
class C extends A
{
private int c;
}

类B和C之间有一些公共字段,这些字段保存在它们的父类A中。以下是测试仪类

class TesterClass
{
static String bOrC = "C"; // input from some decision
public static void main(String[] args) // assume this to be the client
{
A a;
if (bOrC.equals("B")) {
B b = new B();
b.setB(11);
a = b;
} else {
C c = new C();
c.setC(12);
a = c;
}
a.setA(10);
doSomething(bOrC, a);
}
// Below are the service methods
// only this method in the service exposed
public static void doSomething(String bOrC, A a) {
if (bOrC.equals("B")) {
doSomethingWithB(a);
} else if (bOrC.equals("C")) {
doSomethingWithC(a);
}
}
public static void doSomethingWithB(A a) {
B b = (B) a; // possible ClassCastException
System.out.println(b.getA());
System.out.println(b.getB());
}
public static void doSomethingWithC(A a) {
C c = (C) a; // possible ClassCastException
System.out.println(c.getA());
System.out.println(c.getC());
}
}

现在我看到的问题是不安全的动态类型铸造,它可能会引发类铸造问题。一种可能的解决方案是创建单独的数据对象,并在类B和类C中分别为这两个对象设置公共字段(对于我的实际情况来说太多了(,然后看起来如下:

public class TesterClass
{
static String bOrC = "C"; // input from some decision
public static void main(String[] args)
{
if (bOrC.equals("B")) {
B b = new B();
b.setA(10); // duplication
b.setB(11);
doSomethingWithB(b);
} else {
C c = new C();
c.setA(10); // duplication
c.setC(12);
doSomethingWithC(c);
}
}
public static void doSomethingWithB(B b) {
System.out.println(b.getA());
System.out.println(b.getB());
}
public static void doSomethingWithC(C c) {
System.out.println(c.getA());
System.out.println(c.getC());
}
}

我正在寻找一种方法来避免这种动态类型转换,但同时又避免重复公共变量。有人能提出解决方案吗?

抽象是您正在解释的行为的一种解决方案。在类A中创建一个抽象方法doSomething(…(,并分别在子类B和C中实现它。通过这样做,您不需要有一个静态方法,处理将基于B或C对象本身的实例进行。

@Data
class A
{
private int a;
public abstract void doSomething();
}
@Data
class B extends A
{
private int b;
public void doSomething(){
/*.... do something here
* here you can also access parent public methods and properties.
* as you have already annotated with @Data you will have access to getA() method, * hence you can also use parent properties.
*/
}
}
@Data
class C extends A
{
private int c;
public void doSomething(){
/*.... do something here
* here you can also access parent public methods and properties.
* as you have already annotated with @Data you will have access to 
* getA()         method, * hence you can also use parent properties.
*/
}

现在你可以在下面使用它

public static void main(Strings[] args){
A a;
B b = new B();
b.setB(10);
b.doSomething();
C c = new C();
c.setC(30);
c.doSomething();
}

最新更新