在第三方庫我使用的,有層次的下列位:使用第三方抽象類就好像它是一個接口?
public abstract class Foo
{
// Class is public in the Java sense and public in the library's API
}
public class FooImpl extends Foo
{
// While this class is public in the Java sense, it is
// NOT part of the public API and is not even documented
// Library functions that hand back instances of this class
// hand them back as type Foo
}
庫中的各種方法對Foo
類型的東西進行操作。 Foo
文檔說,用戶可以擴展Foo
作出具體的實現,並且(顯然)該庫提供了一個具體的實現。
我很高興圖書館提供的實現,除了一種方法,其行爲我想改變一點。但是我所提供的層次讓我感到沮喪。
如果Foo
是一個接口(這是不是!),我只是這樣做:
public FooWrapper implements Foo
{
private Foo wrappedImpl;
public FooWrapper(Foo toBeWrapped) {
wrappedImpl = toBeWrapped;
}
List<Whatever> methodIWantToTweak() {
List<Whatever> list = wrappedImpl.methodIWantToTweak();
do_something_to_list(list);
return list;
}
Something methodThatsOk() {
return wrappedImpl.methodThatsOk();
}
// similar delegations for remaining methods
}
但因爲它是不是的接口,我不能這樣做,或者至少不能做得乾乾淨淨。
我能想到這樣做的唯一的事情是:
1)擴展API,非公共類FooImpl並重寫我想調整的方法。
2)做這樣的事情:
public class FooWrapper extends Foo
{
private Foo wrappedImpl;
public FooWrapper(Foo toBeWrapped) {
super();
wrappedImpl = toBeWrapped;
}
List<Whatever> methodIWantToTweak() {
List<Whatever> list = wrappedImpl.methodIWantToTweak();
do_something_to_list(list);
return list;
}
Something methodThatsOk() {
return wrappedImpl.methodThatsOk();
}
// Override all non-final public, protected, and package-local
// methods and delegate them to wrappedImpl
}
這兩項辦法聞起來像見鬼了我。第一個問題是它依賴於它不應該知道的類,以及在未來版本的庫中可以更改/消失/重命名的類。第二個問題是FooWrapper
的超類片段沒有被實際使用,並且不可能覆蓋Foo
的任何最終或私有方法(這會導致問題,因爲在那些情況下無法委託給wrappedImpl
)。
我想我必須採用第一種方法,因爲至少它會給出正確的行爲,而第二種可能會以潛在的惡劣,細微的方式破壞,具體取決於Foo
的內部細節。
我剛好運氣好嗎?我忽略了什麼其他方法/想法?
爲什麼你不能覆蓋你想調整的方法?你可以提供相同的實現,除非你調用base而不是wrappedImpl。我錯過了什麼嗎? – dasblinkenlight
@dasblinkenlight - 你可能會丟失的是,OP可能無法改變創建Foo實例的代碼,使其創建* his * Foo子類的實例。包裝可以解決這個問題。 –