[英]How to add an abstract class in the middle with a call to a function using java?
I have the following structure: 我有以下结构:
public abstract class BaseCall<T> implements Callable<T> {
public abstract T innerCall();
protected Structure getProxy() {
return SomeStructure;
}
}
And at least 4 classes that look like that: 至少有四个类似的类:
public class GetXCall extends BaseCall<Set<String>> {
private final Credentials credentials;
public GetXCall (Credentials credentials) {
this.credentials = credentials;
}
@Override
public Set<String> innerCall() {
return getProxy().getXfromVC(credentials);
}
}
public class GetYCall extends BaseCall<Set<String>> {
private final Credentials credentials;
public GetYCall (Credentials credentials) {
this.credentials = credentials;
}
@Override
public Set<String> innerCall() {
return getProxy().getYfromVC(credentials);
}
}
I'm trying to figure out how to make it prettier and add another abstract class in the middle so I can just pass the function getYfromVC
or getXfromVC
and the abstract class will call something like : 我试图弄清楚如何使其更漂亮,并在中间添加另一个抽象类,这样我就可以传递函数
getYfromVC
或getXfromVC
,并且抽象类将调用类似的内容:
getProxy()._____(credentials)
This is what I tried but it doesn't seem to work as I can't use run
inside 这是我尝试过的方法,但是似乎无法正常
run
因为我无法使用run
inside
public abstract class RunVcTask<T> extends BaseCall<T> {
private final Credentials credentials;
public RunVcTask(Credentials credentials) {
this.credentials = credentials;
}
public abstract T run();
@Override
public T innerCall() {
return getProxy().run(credentials); //HERE the run can't work
}
}
As InnerCall
not always uses credentials, I can't change it to abstract innerCall(Credentials c)
由于
InnerCall
并非始终使用凭据,因此无法将其更改为abstract innerCall(Credentials c)
can someone advise if there is a nice way to do it? 有人可以建议是否有很好的方法吗? (I'm currently using java 7)
(我目前正在使用Java 7)
If you stick to inheritance, there is no simplification possible beyond 如果您坚持继承,那么除了简化之外别无他法
public abstract class BaseCall<T> implements Callable<T> {
public abstract T innerCall();
protected Structure getProxy() {
return SomeStructure;
}
}
public abstract class RunVcTask<T> extends BaseCall<T> {
private final Credentials credentials;
public RunVcTask(Credentials credentials) {
this.credentials = credentials;
}
public abstract T actualOp(Structure proxy, Credentials credentials);
@Override
public T innerCall() {
return actualOp(getProxy(), credentials);
}
}
public class GetXCall extends RunVcTask<Set<String>> {
public GetXCall(Credentials credentials) {
super(credentials);
}
@Override
public Set<String> actualOp(Structure proxy, Credentials credentials) {
return proxy.getXfromVC(credentials);
}
}
public class GetYCall extends RunVcTask<Set<String>> {
public GetYCall(Credentials credentials) {
super(credentials);
}
@Override
public Set<String> actualOp(Structure proxy, Credentials credentials) {
return proxy.getXfromVC(credentials);
}
}
A better approach is using delegation : 更好的方法是使用委托 :
public class RunVcTask<T> extends BaseCall<T> {
interface ActualTask<T> {
T actualOp(Structure proxy, Credentials credentials);
}
enum BuiltIn implements ActualTask<Set<String>> {
GetX {
public Set<String> actualOp(Structure proxy, Credentials credentials) {
return proxy.getXfromVC(credentials);
}
},
GetY {
public Set<String> actualOp(Structure proxy, Credentials credentials) {
return proxy.getYfromVC(credentials);
}
},
}
private final Credentials credentials;
private final ActualTask<T> delegate;
public RunVcTask(Credentials credentials, ActualTask<T> task) {
this.credentials = credentials;
this.delegate = task;
}
@Override
public T innerCall() {
return delegate.actualOp(getProxy(), credentials);
}
}
Here, no special subclass for GetX
, GetY
, etc is needed, you can instantiate such a call via 在这里,不需要
GetX
, GetY
等特殊的子类,您可以通过实例化此类调用
BaseCall<Set<String>> getXInstance = new RunVcTask<>(credentials, RunVcTask.BuiltIn.GetX);
BaseCall<Set<String>> getYInstance = new RunVcTask<>(credentials, RunVcTask.BuiltIn.GetY);
so the specialization code of a particular function reduces to the four lines within the BuiltIn
enum
. 因此,特定功能的专业化代码减少到
BuiltIn
enum
内的BuiltIn
。 Only actions with the same return type can be aggregated within such an enum
, so you would have to use multiple enum
s for different types (they don't need to be nested within RunVcTask
) or use anonymous inner classes instead, which is only slightly bigger: 只有具有相同返回类型的动作才能在这样的
enum
聚合,因此您将必须对不同类型使用多个enum
(它们不必嵌套在RunVcTask
),或者使用匿名内部类代替,这仅需一点点大:
BaseCall<Set<String>> getXInstance = new RunVcTask<>(credentials,
new RunVcTask.ActualTask<Set<String>>() {
public Set<String> actualOp(Structure proxy, Credentials credentials) {
return proxy.getXfromVC(credentials);
}
});
BaseCall<Set<String>> getYInstance = new RunVcTask<>(credentials,
new RunVcTask.ActualTask<Set<String>>() {
public Set<String> actualOp(Structure proxy, Credentials credentials) {
return proxy.getYfromVC(credentials);
}
});
You could also use anonymous inner classes of RunVcTask
in the inheritance example, shortening the code to a similar degree, but the delegation approach also provides you with a road map to Java 8, once you are able to switch: 您还可以在继承示例中使用
RunVcTask
匿名内部类,将代码缩短到类似的程度,但是一旦能够切换,委托方法还为您提供了通往Java 8的路线图:
BaseCall<Set<String>> getXInstance = new RunVcTask<>(credentials, Structure::getXfromVC);
BaseCall<Set<String>> getYInstance = new RunVcTask<>(credentials, Structure::getYfromVC);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.