如何在使用 java 调用函数的中间添加抽象 class?

How to add an abstract class in the middle with a call to a function using java?

我有以下结构:

public abstract class BaseCall<T> implements Callable<T> {

    public abstract T innerCall();

    protected Structure getProxy() {
       return SomeStructure;
    }
}

至少有 4 个 class 看起来像这样:

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);
    }
}

我想弄清楚如何让它更漂亮并在中间添加另一个抽象 class 这样我就可以传递函数 getYfromVCgetXfromVC 和抽象class 会调用类似的东西:

getProxy()._____(credentials)

这是我试过的方法,但它似乎不起作用,因为我不能在里面使用 run

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
    }
}

由于 InnerCall 并不总是使用凭据,我无法将其更改为 abstract innerCall(Credentials c)

有人可以建议是否有好的方法吗? (我目前正在使用 java 7)

如果你坚持继承,就没有超越的可能了

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);
    }
}

更好的方法是使用 委托:

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);
    }
}

这里不需要GetXGetY等特殊的子类,可以通过

实例化这样的调用
BaseCall<Set<String>> getXInstance = new RunVcTask<>(credentials, RunVcTask.BuiltIn.GetX);
BaseCall<Set<String>> getYInstance = new RunVcTask<>(credentials, RunVcTask.BuiltIn.GetY);

所以特定函数的专业化代码减少到 BuiltIn enum 中的四行。只有具有相同 return 类型的操作才能在这样的 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);
        }
    });

您也可以在继承示例中使用 RunVcTask 的匿名内部 类,将代码缩短到类似程度,但委托方法也为您提供了 [=35] 的路线图=] 8,一旦你能够切换:

BaseCall<Set<String>> getXInstance = new RunVcTask<>(credentials, Structure::getXfromVC);
BaseCall<Set<String>> getYInstance = new RunVcTask<>(credentials, Structure::getYfromVC);