【问题标题】:Avoiding Dynamic Type Casting with Inheritance for Data Classes in Java避免使用 Java 中数据类的继承进行动态类型转换
【发布时间】:2020-04-14 16:08:02
【问题描述】:

我有 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());
    }
}

我正在寻找一种方法来避免这种动态类型转换,但同时避免必须复制公共变量。任何人都可以提出解决方案吗?

【问题讨论】:

  • 你不能把B b 传给doSomethingWithBC c 传给doSomethingWithC吗?
  • 我很抱歉造成混乱。我已经稍微编辑了代码。你能再检查一下吗?

标签: java inheritance casting code-duplication


【解决方案1】:

抽象是您正在解释的行为的一种解决方案。在类 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();
   }

【讨论】:

  • 嗨 Nimesh,您能根据我的示例提供示例代码 sn-p 吗?那会很有帮助
猜你喜欢
  • 2021-01-29
  • 2013-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-14
相关资源
最近更新 更多