How to extend a final class in Java
Solution 1
You can't, basically. It looks like the developer who designed Bar
intended for it not to be extended - so you can't extend it. You'll need to look for a different design - possibly one which doesn't use inheritance so much... assuming you can't change the existing code, of course.
(It's hard to give more concrete advice without knowing more about the real goal here - the design of the overall system.)
Solution 2
You can't extend a class that is declared final
. However you can create an intermediate class, called Wrapper
. This Wrapper will basically contain an instance of the original class and provide alternative methods to modify the state of the object according what you want to do.
Of course this will not give access to the private & protected fields of the final
class, but you can use its getters and setters methods, combined with the new methods & fields you declared in the Wrapper
class to get the result you want to, or something relatively close.
Another solution is not to declare final
a class if there is no valid reason to do it.
Solution 3
You can't extend a final
class - that's the purpose of the final
keyword.
However, there are (at least) two work-arounds:
- The class is in the Jenkins project, which is open source, so you can just download the project, make the changes you want to the class and re-build the jar
- Somewhat of a hack, but you could use a library like Javassist to replace the implementation of the class in memory
Solution 4
You cannot extend final classes, that is the point of declaring classes final. You can define an interface that both the final class inherit from and a wrapper class that delegates calls to the wrapped final class. The question is then why to make the class final in first place.
Solution 5
Probably what you want is a Proxy. It's easy to implement. This is a great article: http://blog.frankel.ch/the-power-of-proxies-in-java
Dimitri
Updated on January 13, 2021Comments
-
Dimitri over 3 years
Here is my problem actually I'm facing now. I have a class, let's say
Foo
and this class defines a method calledgetBar
that returns aBar
instance. The classBar
is defined insideFoo
and and is declaredpublic static final
. What I want to do is to define a classMyFoo
that extendsFoo
but I also want to extendBar
withMyBar
by adding my own functionalities (methods, properties,etc). I also wantgetBar
to returnMyBar
.The problem is
Bar
is final. Here is an illustration of what I want to do :public class Foo { Bar bar = new Bar(); public Bar getBar(){ return bar; } .... public static final class Bar { } }
What I want to do is :
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 } }
How can I achieve that?
[EDIT] I am adding more details to my question. I am actually developing a plugin for Jenkins and after searching, I realize there is a plugin that offers the base functionalities that I want to do,
Foo
andBar
. I want to customFoo
andBar
, so it can fits my needs. Foo is the main class of the plugin and extends a class called Builder. Foo defines a method calledperform
which contains all the operations for performing a build.Bar
contains operations for configurations purposes and Foo needs Bar to get those informations.So what I want to do is to extend Foo with
MyFoo
and add some configurations withMyBar
. And as you see,MyFoo
will need to get those configuations by callinggetBar();
The second thing is I have no control of the instanciation of
MyFoo
andMyBar
What blocks me, is that I cannot extend Bar. How can I achieve that?