Re: final methods and classes
On Oct 12, 4:30 am, Lew <no...@lewscanon.com> wrote:
Lionel van den Berg wrote:
Just wondering what arguments there are out there for making methods
and classes final when they are not expected to be overridden/
extended? Typically I would make them final, but when I'm doing code
reviews I don't raise this as an issue because I see it is relatively
trivial.
Arne Vajh=F8j wrote:
In my opinion none it is a leftover from the very early days of Java.
See:
http://www.ibm.com/developerworks/java/library/j-jtp1029.html
Sorry about the accidental post. I had intended to write:
Excellent link, Arne. However, that very article gives many good reaso=
ns for
using the 'final' keyword, contradicting your notion that there aren't go=
od
reasons for it.
From an API writer's perspective, that is, anyone writing classes inte=
nded to
be used, 'final' on a class or method indicates that it should not, and
therefore cannot be extended / overridden. As Mr. Goetz said in the
referenced article, this decision should be documented (in the Javadocs).
There's a difference between something "you should not do" and
something you are prohibited from doing. The creator of a class should
clearly document that s/he didn't design it to be extensible using
inheritance, but s/he should think twice about making it non-
extensible forever. Sometimes the classes we write can be used in a
way we didn't anticipate, and that's not automatically a bad thing.
Josh Bloch in /Effective Java/ suggests that one should prefer compositio=
n to
inheritance, and that inheritance is somewhat abused. ("Design and doc=
ument
for inheritance or else prohibit it") He advises to make classes final=
unless
you explicitly and properly make them heritable.
I would gladly accept such advice if there was a thing like
composition as a first-class concept in Java; e.g. if you were able to
say
public class Example extends X implements Y uses Z(z) {
private Z z; //Error if z is not assigned a value by a constructor
public Example(Z z) {
this.z = z;
}
...
}
and automatically have methods in the implemented interfaces delegated
to z, unless you override them. That is not the case, and composition,
while being the right thing in certain cases, is way more cumbersome
and "foreign" than inheritance, and thus can't be used as a general
substitute for inheritance.
It's like saying that pure functions are to be preferred over
functions with side effects: that might be true in a language with
heavy support for functional programming, but giving it as an advice
for good Java coding would be wrong.
Alessio