这是我现在面临的问题。
我有一个类,比方说Foo
,这个类定义了一个名为getBar
的方法,它返回一个Bar
实例。类Bar
在Foo
内定义,并声明为public static final
。我想要做的是定义一个扩展MyFoo
的类Foo
,但我还希望通过添加我自己的功能(方法,属性等)来扩展Bar
和MyBar
。 )。
我还希望getBar
返回MyBar
。
问题是Bar
是最终的。以下是我想要做的事情的说明:
public class Foo {
Bar bar = new Bar();
public Bar getBar(){
return bar;
}
....
public static final class Bar {
}
}
我想做的是:
public class MyFoo extends Foo {
public MyBar getBar(){ // here I want to return an instance of MyBar
}
public static final class MyBar extends Bar { // That's impossible since Bar is final
}
}
我怎样才能做到这一点?
[编辑]我正在为我的问题添加更多细节。
我实际上正在为Jenkins开发一个插件,在搜索之后,我意识到有一个插件提供了我想要做的基本功能,Foo
和Bar
。我想自定义Foo
和Bar
,因此它可以满足我的需求。
Foo是插件的主要类,并扩展了一个名为Builder的类。 Foo定义了一个名为perform
的方法,其中包含执行构建的所有操作。
Bar
包含用于配置目的的操作,Foo需要Bar来获取这些信息。
所以我想做的是使用MyFoo
扩展Foo并使用MyBar
添加一些配置。如您所见,MyFoo
需要通过调用getBar();
第二件事是我无法控制MyFoo
和MyBar
阻止我的是,我无法延伸Bar。我怎样才能做到这一点?
答案 0 :(得分:29)
Bar
的开发人员不打算扩展它 - 所以你不能扩展它。你需要寻找一个不同的设计 - 可能是一个不使用继承的设计......当然,假设你不能改变现有的代码。
(如果不了解更多关于这里的真正目标 - 整个系统的设计,很难提出更具体的建议。)
答案 1 :(得分:9)
您无法扩展声明为final
的类。但是,您可以创建一个名为Wrapper
的中间类。这个Wrapper基本上包含原始类的一个实例,并根据你想要的内容提供修改对象状态的替代方法。
当然,这不会提供访问私人& final
类的受保护字段,但您可以使用其getter和setter方法,结合新方法和&您在Wrapper
类中声明的字段,以获得您想要的结果,或者相对接近的结果。
如果没有合理的理由,另一种解决办法就是不要宣布final
一个类。
答案 2 :(得分:7)
您无法扩展final
课程 - 这是final
关键字的目的。
然而,(至少)有两种解决方法:
答案 3 :(得分:4)
你不能扩展最终的类,这是宣告类最终的要点。您可以定义最终类继承的接口和将调用委托给包装的最终类的包装类。问题是为什么要让班级最终成为最终的。
答案 4 :(得分:2)
您可能想要的是代理服务器。它很容易实现。这是一篇很棒的文章:http://java.dzone.com/articles/power-proxies-java
答案 5 :(得分:0)
例如,我们无法在TreeSet集合中添加StringBuffer,因为 TreeSet不是Interface Comparable的子代:
public class Main(){
public static void main(String[] args){
TreeSet treeSetSB = new TreeSet();
treeSetSB.add(new StringBuffer("A")); //error, Comparable is not implemented
}
但是我们可以使用包装器来实现Comparable:
class myWrap implements Comparable{
TreeSet treeset;
public myWrap() {
this.treeset=new TreeSet<>();
}
public TreeSet getTreeset() {
return treeset;
}
public void setTreeset(TreeSet treeset) {
this.treeset = treeset;
}
}
public class Main(){
public static void main(String[] args){
myWrap myWrap =new myWrap();
TreeSet myTrs =myWrap.getTreeset();
myTrs.add("b"); // no error anymore
myTrs.add("a");
myTrs.add("A");
System.out.println(myTrs);
}
答案 6 :(得分:0)
如果它实现了某些接口,Decorator Design pattern可以解决问题。