2017-01-09 17 views
0

我有以下結構:如何在使用java調用函數的過程中添加抽象類?

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

    public abstract T innerCall(); 

    protected Structure getProxy() { 
     return SomeStructure; 
    } 
} 

和至少4個看起來像類:

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

我想弄清楚如何讓它更漂亮,並添加另一個抽象類中中間這樣我就可以傳遞給函數getYfromVCgetXfromVC和抽象類將調用類似:

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)

+0

你會ju ST必須調用它getfromVC() –

+0

什麼?你能解釋一下嗎? getProxy()不能調用'run' – user1386966

+0

你的類已經很簡單了,不清楚爲什麼你需要更簡化它 –

回答

1

如果你堅持繼承,沒有超出

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

因此特定功能的專業化代碼縮減爲BuiltInenum內的四行。只有具有相同返回類型的動作可以在這樣的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匿名內部類的繼承示例,代碼縮短程度相似,但代表團的做法也爲您提供了一個路線圖,到Java 8,一旦你能切換:

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