如何在Java中扩展最终类

Dim*_*tri 17 java static final

这是我现在面临的问题.我有一个类,比方说Foo,这个类定义了一个getBar返回Bar实例的方法.该类Bar在内部定义Foo,并被声明public static final.我想要做的就是定义一个类MyFoo扩展Foo,但我也想对BarMyBar加入我自己的功能(方法,属性等).我也想getBar回来MyBar.

问题Bar是最终的.以下是我想要做的事情的说明:

public class Foo {

  Bar bar = new Bar();

  public Bar getBar(){
      return bar;
  } 

   ....

   public static final class Bar {

    } 
}
Run Code Online (Sandbox Code Playgroud)

我想做的是:

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

  } 
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

[编辑]我正在为我的问题添加更多细节.我实际上正在为Jenkins开发一个插件,在搜索之后,我意识到有一个插件提供了我想要做的基本功能,Foo并且Bar.我想定制FooBar,因此它可以适合我的需要.Foo是插件的主要类,并扩展了一个名为Builder的类.Foo定义了一个方法perform,该方法包含执行构建的所有操作. Bar包含用于配置目的的操作,Foo需要Bar来获取这些信息.

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

第二件事是我无法控制MyFoo和的实现MyBar

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

Jon*_*eet 29

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

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


fla*_*yte 10

您不能扩展声明的类final.但是,您可以创建一个名为的中间类Wrapper.这个Wrapper基本上包含原始类的一个实例,并根据你想要的内容提供修改对象状态的替代方法.

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

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


Boh*_*ian 7

你不能扩展一个final类 - 这是final关键字的目的.

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

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

  • 为什么有人会参加班级期末考试?这听起来像是一个可怕的问题,但我是编程新手。我试图扩展 Scanner 类(只是为了看看我是否可以),但我发现它不起作用。我的朋友告诉我这是因为扫描仪课程是期末考试。假设理论上它不是最终版本,有人确实扩展了它。由于子类中更改的任何变量不必更改父类,会出现什么问题?等等。 (2认同)

小智 5

也许您想要的是代理。它很容易实现。这是一篇很棒的文章:http ://blog.frankel.ch/the-power-of-proxies-in-java