Stopping inheritance without using final

14,710

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 { ... }
}
Share:
14,710
Admin
Author by

Admin

Updated on July 26, 2022

Comments

  • Admin
    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
    vava over 15 years
    I actually believe that's the best solution ever. You could even describe why it shouldn't to be inherited from.
  • Peter Štibraný
    Peter Štibraný over 15 years
    Inheritance is way overrated. Unless you design your class for subclassing, you better avoid it.
  • palantus
    palantus over 15 years
    Rats, I was just going to post the exception one myself.
  • jcollum
    jcollum over 15 years
    +1, I'm betting that Uncle Bob Martin knows more about OO than just about anyone here.
  • Jon Skeet
    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
    Brett over 15 years
    Except if the finalize method is overriden, the instance can be recovered.
  • palantus
    palantus over 15 years
    "Design and document for inheritance or else prohibit it." -- Josh Bloch, Effective Java Item 17
  • Draiget
    Draiget over 15 years
    Read 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
    eleven81 over 15 years
    The comment idea really does not make much sense. A JavaDoc comment makes a lot more sense, but is still not foolproof.
  • duffymo
    duffymo over 15 years
    Reasons similar to java.lang.String, I'd guess.
  • Tim Frey
    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
    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
    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
    O.Badr over 2 years