下面是我想要完成的一個例子。我正在嘗試創建LibraryRunner哪些 implements GenericRunner。但是,我收到了一個 IDE 警告,LibraryRunner它沒有實作GenericRunner介面中的方法。這是有道理的,方法簽名不匹配,但是如何在仍然使用LibraryCalculatorwhich extends the 的同時使方法簽名匹配GenericCalculator?
public class LibraryRunner implements GenericRunner {
@Override
public <T> T run(LibraryCalculator<T> calculator) {
return new Object();
}
}
public interface GenericRunner {
<T, A> T run(GenericCalculator<T, A> calculator);
}
public interface LibraryCalculator<T> extends GenericCalculator<T, LibraryAlgorithm> {
T calc(LibraryAlgorithm algorithm) throws LibraryException;
}
public interface GenericCalculator<T, A> {
T calc(A algorithm) throws Exception;
}
public class LibraryException extends Exception {
}
uj5u.com熱心網友回復:
定義介面的方式,您不能覆寫該方法并更改其簽名,即使LibraryCalculator是GenericCalculator. 另一個答案解釋了原因。
解決這個問題的一種方法是GenericRunner使用計算器型別引數化介面:
public interface GenericRunner<T, A, C extends GenericCalculator<T, A>> {
T run(C calculator);
}
public class LibraryRunner<T> implements GenericRunner<T, LibraryAlgorithm, LibraryCalculator<T>> {
@Override
public T run(LibraryCalculator<T> calculator) {
...
}
}
但請注意,您不能Object在LibraryRunner方法中回傳 an,因為它不匹配T。如果你想回傳一個特定的型別Object(這違背了 generic 的目的LibraryCalculator),你必須明確地指定它:
public class LibraryRunner implements GenericRunner<Object, LibraryAlgorithm, LibraryCalculator<Object>> {
@Override
public Object run(LibraryCalculator<Object> calculator) {
return new Object();
}
}
如果這不是您想要的,那么由用戶LibraryRunner決定T應該系結哪種型別。
uj5u.com熱心網友回復:
當你重寫或實作一個方法時,你總是需要滿足被重寫方法的條件,例如你應該仍然能夠呼叫帶有引數 GenericCalculator 的 LibraryRunner.run。否則寫下去沒有意義:
LibraryRunner libRunner = new LibraryRunner();
GenericRunner genRunner = libRunner;
genRunner.run(new GenericCalculator<>());
覆寫例外確實有效,因為當您呼叫時,GenericCalculator.calc您會期待任何例外并將LibraryCalculator.calc其范圍縮小到 only LibraryException。
您可以將覆寫方法視為承諾更多資訊。
uj5u.com熱心網友回復:
我認為這GenericRunner沒有必要。它所做的只是將泛型型別引數從類級別移動到方法級別。而是使用Callable<T>. LibraryRunner如您所知,原樣的問題在于它不能在任何地方都GenericRunner可以使用,因為它的方法只接受它“應該”的物件子集。這個論點就是問題所在。某些類需要提供它,但我認為當前的更高層次的介面已經將責任推得太遠了。通常,您將擁有實作類構造,或在其建構式中接受此類引數。像這樣的東西:
public class LibraryRunner<T> implements Callable<T> {
private final LibraryAlgorithm algorithm;
private final Supplier<LibraryCalculator<T>> calculatorSupplier;
public LibraryRunner(
LibraryAlgorithm algorithm,
Supplier<LibraryCalculator<T>> calculatorSupplier) {
this.algorithm = algorithm;
this.calculatorSupplier = calculatorSupplier;
}
@Override
public T call() throws Exception {
return calculatorSupplier.get().calcT(algorithm);
}
}
通過Supplier您提供給建構式的 ,您可以LibraryCalculator控制LibraryRunner.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/415335.html
標籤:
上一篇:npminstall有警告問題
