这是我的问题,实际上我现在面对。 我有一个类,让我们说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
}
}
我怎样才能做到这一点?
[编辑]我加入更多的细节,我的问题。 我其实开发詹金斯插件和搜索后,我意识到的是,提供了我想要做的,基本的功能插件Foo
和Bar
。 我想定制Foo
和Bar
,所以它可以适合我的需要。 foo是主类的插件和扩展名为生成器类。 foo定义调用方法perform
它包含的所有操作进行构建。 Bar
包含操作的配置目的和Foo需要律师来获得这些信息。
因此,我想要做的就是美孚与扩展MyFoo
,并加入一些配置MyBar
。 正如你看到的, MyFoo
将需要通过调用来获得这些configuations getBar();
第二件事是我没有的instanciation的控制MyFoo
和MyBar
什么块我,是我不能延伸吧。 我怎样才能做到这一点?
你不能,基本上是这样。 它看起来像谁设计的开发人员Bar
预期它不被扩展-所以你不能扩展。 你需要寻找一个不同的设计 - 可能一个不使用继承了这么多......假如你不能改变现有的代码,当然。
(很难不知道在此处详细了解真正的目标给予更多的具体建议 - 整个系统的设计)
你无法扩展声明一个类final
。 但是你可以创建一个中间类,称为Wrapper
。 此包装将基本包含原始类的一个实例,并提供替代方法根据你想要做什么修改对象的状态。
当然,这不会给访问的私人及保护领域的final
类,但你可以使用它的getter和setter方法,用新的方法和字段结合您在声明Wrapper
类来得到你想要的结果,或东西比较接近。
另一种解决方案是不申报final
一类,如果没有有效的理由这样做。
你不能扩展final
类-这就是目的final
关键字。
不过,也有(至少)两个变通办法:
- 类是在詹金斯项目,该项目是开源的,所以你可以下载项目,让你想班上更改并重新构建JAR
- 有点一个黑客攻击,但你可以使用像库Javassist进行更换内存中的类的实现
不能扩展final类,即宣告类最后的点。 您可以定义,无论是最后一类从继承的接口和包装类,委托调用包裹最后一类。 接下来的问题是,为什么使课堂最终排在首位。
也许你想要的是一个代理。 这很容易实现。 这是一个伟大的文章: http://java.dzone.com/articles/power-proxies-java
例如,我们不能在TreeSet中Collection中添加一个StringBuffer,因为TreeSet的接口没有可比的孩子:
public class Main(){
public static void main(String[] args){
TreeSet treeSetSB = new TreeSet();
treeSetSB.add(new StringBuffer("A")); //error, Comparable is not implemented
}
但是,我们可以使用一个包装来实现可比:
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);
}
如果实现了一些接口, 装饰设计模式可以解决这个问题。