【问题标题】:How to return a static instance in subclass type如何以子类类型返回静态实例
【发布时间】:2016-02-25 13:47:57
【问题描述】:

我目前是两个班。带有简单属性“responseCode”的响应。响应有一个静态实例(当它是 KO 时是一个简单的响应)。

我还有一个类 DetailResponse,它是我的类 Response 的子类。

我要做的是能够在 Response 类中使用我的静态变量 KO_RESPONSE 返回一个 DetailResponse 类型的对象。有没有办法简单地做到这一点?

我的超班回应:

public class Response {
    public static final Response KO_RESPONSE = new A(ReturnCode.KO);

    public ReturnCode responseCode;
    public String comment;

    public Response () {};
    public Response (ReturnCode responseCode) {
        this.responseCode = responseCode;
    }

    public static enum ReturnCode {
        OK,
        KO;
    }
}

我的子类 DetailResponse 扩展了 Response :

public class DetailResponse extends Response {
    public String otherField;
}

商务服务类:

public BuisinessService {
    public DetailResponse sendRequest() {
        String status = sendRequest() // Do something
        if(status.equals("KO")) {
            return Response.KO_RESPONSE; // What I would do but doesn't work because Response is the super class of DetailResponse
        } else {
            DetailResponse detail = new DetailResponse(ReturnCode.OK);
            detail.comment = "comment";
            detail.otherField = "somethingCool";
            return detail;
        }
    }
}

【问题讨论】:

  • 为什么不直接返回一个新的DetailResponse 实例,并带有适当的返回码,而不需要额外的数据?您不能使用静态字段并在运行时更改其类型,如果您想使用静态字段(或静态工厂方法),您必须为每种类型提供一个并相应地选择。
  • 您是否需要让Response.KO_RESPONSE 成为(非详细信息)Response?还是它总是DetailResponse 类型?
  • @Thomas 我猜你是对的。我想做一些容易阅读的事情。我认为可以用泛型类型和静态工厂做一些事情,但它仍然会比简单的构造函数更复杂。
  • @bradimus 是的,它将是一个 DetailResponse。
  • 然后要么按照@Thomas 的建议去做,要么将静态实例移到子类中。

标签: java inheritance static


【解决方案1】:

您正试图覆盖static 变量,Java 不允许这样做。相反,您可以实现以下模式来获取基类和子类的实例。这是一个例子:

    public class Response {
     public static Response getInstance(){
      return new Response(<args>);
     }
    }

    public class DetailedResponse extends Response {
     public static DetailedResponse getInstance(){
      return new DetailedResponse(<args>);
     }
    }

最后商务舱可以实现如下:

public BuisinessService {
    public DetailResponse sendRequest() {
        String status = sendRequest() // Do something
        if(status.equals("KO")) {
            return DetailResponse.getInstance(); // What I would do but doesn't work because Response is the super class of DetailResponse
        } else {
            DetailResponse detail = new DetailResponse(ReturnCode.OK);
            detail.comment = "comment";
            detail.otherField = "somethingCool";
            return detail;
        }
    }
}

希望这会有所帮助!

【讨论】:

  • 如果你每次getInstance()都返回一个新实例,你就没有单例。
  • 是的,我们不会称它为单例。虽然这满足了 Thomas 的要求。谢谢,我会编辑我的答案。
【解决方案2】:

静态变量和方法不会被继承,但你可以使用静态块初始化器

public class Response {
        public static Response KO_RESPONSE;

        public ReturnCode responseCode;
        public String comment;

        public Response () {};
        public Response (ReturnCode responseCode) {
            this.responseCode = responseCode;
        }

        public static enum ReturnCode {
            OK,
            KO;
        }
    }

    public class DetailResponse extends Response {

        static {
            Response.KO_RESPONSE = new DetailResponse(/* .. */);
        }

        public String otherField;
    }

【讨论】:

  • 这似乎是个坏主意。如果KO_RESPONSE 在类DetailResponse 被加载之前被访问,它将简单地为空。另外,请注意KO_RESPONSE 仅存在一次,因此当其他子类执行类似操作时,它所包含的内容本质上是不确定的。
  • 此外,该字段现在是 public,但不是 final。任何班级都可以重新分配它。
  • 我正在回答他提出的问题。您提到的那些问题是给定代码的设计缺陷,这不是我的错
【解决方案3】:

为什么你在这里使用了 A(),A 没有定义。

public static final Response KO_RESPONSE = new A(ReturnCode.KO);

这里可以使用详细的响应或其他类型的响应

class DetailResponse extends Response {

    public DetailResponse(ReturnCode ko) {
        super(ko);
    }

    public String otherField;
}

class Response {
    public static final Response KO_RESPONSE = new Response(ReturnCode.KO);

    public ReturnCode responseCode;
    public String comment;

    public Response () {};
    public Response (ReturnCode responseCode) {
        this.responseCode = responseCode;
    }

    public static enum ReturnCode {
        OK,
        KO;
    }
}

您还必须为您的详细响应类声明一个可用于定义的参数化构造函数

【讨论】:

  • 这并没有解决问题。
  • @bradimus - 是的,现在我明白 Thomas Betous 的观点了,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-16
  • 2022-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多