如何在Java中扩展最终类

时间:2012-11-08 17:40:05

标签: java static final

这是我现在面临的问题。 我有一个类,比方说Foo,这个类定义了一个名为getBar的方法,它返回一个Bar实例。类BarFoo内定义,并声明为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 {

    } 
}

我想做的是:

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开发一个插件,在搜索之后,我意识到有一个插件提供了我想要做的基本功能,FooBar。我想自定义FooBar,因此它可以满足我的需求。 Foo是插件的主要类,并扩展了一个名为Builder的类。 Foo定义了一个名为perform的方法,其中包含执行构建的所有操作。 Bar包含用于配置目的的操作,Foo需要Bar来获取这些信息。

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

来获取这些配置

第二件事是我无法控制MyFooMyBar

的实例化

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

7 个答案:

答案 0 :(得分:29)

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

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

答案 1 :(得分:9)

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

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

如果没有合理的理由,另一种解决办法就是不要宣布final一个类。

答案 2 :(得分:7)

您无法扩展final课程 - 这是final关键字的目的。

然而,(至少)有两种解决方法:

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

答案 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可以解决问题。