Stopping inheritance without using final
Solution 1
A comment
//Do not inherit please
Solution 2
Two more options:
make each method final, so people can't override them. You avoid accidental calling of methods from subclass this way. This doesn't stop subclassing though.
put check into constructor for class:
if (this.getClass() != MyClass.class) { throw new RuntimeException("Subclasses not allowed"); }
Then nobody will be able to instantiate subclass of your class.
(Not that I suggest using these techniques, it just came to my mind. I would use final class and/or private constructor)
Solution 3
- Use final
- Use private constructors
Use a comment:
// do not inherit
Use a javadoc comment
- Make every method final, so people can't override them
Use a runtime check in the class constructor:
if (this.getClass() != MyClass.class) { throw new RuntimeException("Subclasses not allowed"); }
Solution 4
Final was created to solve this problem.
Solution 5
Make your constructors private and provide factory functions to create instances.
This can be especially helpful when you want to choose an appropriate implementation from multiple, but don't want to allow arbitrary subclassing as in
abstract class Matrix {
public static Matrix fromDoubleArray(double[][] elemens) {
if (isSparse(elements)) {
return new SparseMatrix(elements);
} else {
return new DenseMatrix(elements);
}
}
private Matrix() { ... } // Even though it's private, inner sub-classes can still use it
private static class SparseMatrix extends Matrix { ... }
}
![Admin](/assets/logo_square_200-5d0d61d6853298bd2a4fe063103715b4daf2819fc21225efa21dfb93e61952ea.png)
Admin
Updated on July 26, 2022Comments
-
Admin almost 2 years
Is there any other method of stopping inheritance of a class apart from declaring it as final or by declaring its constructor as private?
-
vava over 15 yearsI actually believe that's the best solution ever. You could even describe why it shouldn't to be inherited from.
-
Peter Štibraný over 15 yearsInheritance is way overrated. Unless you design your class for subclassing, you better avoid it.
-
palantus over 15 yearsRats, I was just going to post the exception one myself.
-
jcollum over 15 years+1, I'm betting that Uncle Bob Martin knows more about OO than just about anyone here.
-
Jon Skeet over 15 years+1 to Peter's comment. As I've said elsewhere (many times!) I wish classes were sealed (C#) / final (Java) by default. Inheritance is great, when you really need it - but it can be a pain if you just use it without thinking carefully about it.
-
Brett over 15 yearsExcept if the finalize method is overriden, the instance can be recovered.
-
palantus over 15 years"Design and document for inheritance or else prohibit it." -- Josh Bloch, Effective Java Item 17
-
Draiget over 15 yearsRead Michael Feather's book "Working Effectively with Legacy Code". It's gotten me through a number of brownfield projects and things like classes and methods you can't touch are major pain points. Even if you didn't intend for it, feature XYZ will need it. All about future proofing...
-
eleven81 over 15 yearsThe comment idea really does not make much sense. A JavaDoc comment makes a lot more sense, but is still not foolproof.
-
duffymo over 15 yearsReasons similar to java.lang.String, I'd guess.
-
Tim Frey over 15 years+1 I didn't think there would be a real answer to this question, but I guess this is as close as you're going to get.
-
Jon Skeet over 15 years@Mark G: Inheritance restricts changes in implementation, so I don't regard allowing it as future-proofing at all. It limits future changes rather than allowing them.
-
Draiget over 15 years@Jon Skeet: I guess in my experience I've just not seen it. Take any of the dialogs in the .NET BCL (Open/Save/Print), can't do a danged thing with them because they're sealed, major pain. But this discussion should probably be in a different question with the tag of 'Subjective'
-
O.Badr over 2 years