繁体   English   中英

使用空抽象类有什么好的替代方法?

[英]What is a good alternative to using an empty abstract class?

假设我有以下内容:

public abstract class AbstractResponse {
  // this class is totally empty!
}

public class ResponseA extends AbstractResponse {
  // JSON POJO 
}

public class ResponseB extends AbstractResponse {
  // JSON POJO 
}

public abstract class AbstractClient {
  public abstract Class getType();

  public AbstractResponse readResponse() {
    ObjectMapper mapper = new ObjectMapper();
    AbstractResponse response;
    try {
        return (AbstractResponse) mapper.readValue(data, getType());
    } catch (IOException e) {...}
  }
}

public class ResponseAClient extends AbstractClient {
  public Class getType() {
    return ResponseA.class;
  }
}

public class ResponseBClient extends AbstractClient {
  public Class getType() {
    return ResponseB.class;
  }
}

除了作为JSON POJO之外, ResponseAResponseB没有任何共同之处。 正如您所看到的,我使用一个空的抽象类AbstractResponse来避免客户端类ResponseAClientResponseBClient中的readResponse()重复代码。

我的问题

对类似的情况使用空的抽象类是不好的做法,如果是这样,那么编码它的最佳方法是什么? 我曾考虑使用泛型,但我看到很多警告不鼓励使用Java Generics。

编辑:谢谢你的快速反应。 在@Kayaman的有用评论之后,我想重新解释我的问题:

对于我上面描述的那种情况,是否有比使用空接口/抽象类更好的实现。 拥有一个空接口/抽象类似乎是不好的做法。

使用界面。 使用空的抽象类是没有意义的(除非你想阻止类继承另一个类)。

至于你的“许多不鼓励使用Java Generics的警告。”,我很高兴看到一些链接,因为那是不正确的。

编辑:通用方法可以提供类似以下内容( Response是一个空接口,用于标记具体响应类并限制Client可以处理的允许类型)

public class Client<T extends Response> {
    private Class<T> clazz;
    public Client(Class<T> clazz) {
        this.clazz = clazz;
    }
    public T readResponse() {
        ObjectMapper mapper = new ObjectMapper();

        return (T) mapper.readValue(data, clazz);
    }
}

允许您处理强类型的响应。

Client<ResponseA> clientA = new Client<>(ResponseA.class);
ResponseA resp = clientA.readResponse();

因此,“对一个空的抽象类有什么好的替代”这个问题的答案是“重构和重新设计”。

我宁愿使用带有@Retention(RetentionPolicy.RUNTIME)的注释,而不是使用空接口或抽象类。 这是要编写的更多代码,并且可能不是特别易读和快速(您要检查类是否具有此批注的部分)。

语言中有空接口,如Serializable 但是从Java 5开始它就不再那么有意义了。

import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

public abstract class AbstractClient {
    public abstract Class getType();

    public Object readResponse() {
        ObjectMapper mapper = new ObjectMapper();
        try {
            Object response = mapper.readValue(data, getType());

            if (response.getClass().getDeclaredAnnotation(Response.class) == null) {
                // Not a valid type
            }

            return response;
        } catch (IOException e) {...}
    }
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface Response {

}

@Response
class ResponseA extends AbstractResponse {
    // JSON POJO
}

@Response
class ResponseB extends AbstractResponse {
    // JSON POJO
}


class ResponseAClient extends AbstractClient {
    public Class getType() {
        return ResponseA.class;
    }
}

class ResponseBClient extends AbstractClient {
    public Class getType() {
        return ResponseB.class;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM