在我正在使用的第 3 方库中,有以下层次结构:
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-non-public 类 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
.
那我是不是运气不好?我忽略了哪些其他方法/想法?