如何在Java中扩展最终类

这是我现在面临的问题。 我有一个类,让我们说Foo ,这个类定义了一个名为getBar的方法,它返回一个Bar实例。 类BarFoo定义,并且被声明为public static final 。 我想要做的是定义一个扩展Foo的类MyFoo ,但我也希望通过添加我自己的function(方法,属性等)来扩展BarMyBar 。 我也想让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开发一个插件,在搜索之后,我意识到有一个插件可以提供我想要做的基本function, FooBar 。 我想定制FooBar ,因此它可以满足我的需求。 Foo是插件的主要类,并扩展了一个名为Builder的类。 Foo定义了一个名为perform的方法,其中包含执行构建的所有操作。 Bar包含用于配置目的的操作,Foo需要Bar来获取这些信息。

所以我想做的是使用MyFoo扩展Foo并使用MyFoo添加一些配置。 如你所见, MyFoo需要通过调用getBar();来获得这些配置getBar();

第二件事是我无法控制MyFooMyBar

阻止我的是,我无法延伸Bar。 我怎样才能做到这一点?

基本上你不能。 看起来设计Bar的开发人员不会扩展它 – 所以你不能扩展它。 你需要寻找一个不同的设计 – 可能是一个不使用inheritance的设计……当然,假设你不能改变现有的代码。

(如果不了解更多关于这里的真正目标 – 整个系统的设计,很难给出更具体的建议。)

您不能扩展声明为final的类。 但是,您可以创建一个名为Wrapper的中间类。 此Wrapper将基本上包含原始类的实例,并提供替代方法来根据您要执行的操作来修改对象的状态。

当然,这不会提供对final类的私有和受保护字段的访问,但是您可以使用其getter和setter方法,结合您在Wrapper类中声明的新方法和字段来获得您想要的结果,或者比较接近的东西。

另一种解决方案是,如果没有合理的理由,则不要声明final的类。

你无法扩展final类 – 这是final关键字的目的。

但是,(至少)有两种解决方法:

  1. 该类位于Jenkins项目中,该项目是开源的,因此您只需下载项目,对类进行所需的更改并重新构建jar
  2. 有点像黑客,但你可以使用像Javassist这样的库来替换内存中类的实现

你不能扩展最终的类,这是宣告类最终的要点。 您可以定义最终类inheritance的接口和将调用委托给包装的最终类的包装类。 问题是为什么要把class级列为最终。

可能你想要的是一个代理。 它很容易实现。 这是一篇很棒的文章: http : //java.dzone.com/articles/power-proxies-java

例如,我们不能在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); } 

如果它实现了一些接口, Decorator Design模式可以解决问题。