9

Is there any other method of stopping inheritance of a class apart from declaring it as final or by declaring its constructor as private?

bdukes
  • 152,002
  • 23
  • 148
  • 175
  • What's wrong with final? – lc. Jan 16 '09 at 17:03
  • could you try to explain why you are trying to avoid the use of the final keyword? – shsteimer Jan 16 '09 at 17:14
  • 1
    Probably because there's a framework involved that creates subclasses. – krosenvold Jan 16 '09 at 17:20
  • i was just trying to find some other ways... they produce interesting results.. I was just curious –  Jan 16 '09 at 17:25
  • ...in which case, there's no way to stop inheritance that also allows inheritance. :-) – Andrzej Doyle Jan 16 '09 at 17:25
  • 1
    @dtsazza There are things a framework could do that you'd normally not let user code do; a framework could change the protection level of a private constructor at run-time. AFIK you cannot mess with final though... – krosenvold Jan 16 '09 at 17:30
  • @dtsazza In effect the framework could have the "dont do this at home, kids" attitude. – krosenvold Jan 16 '09 at 17:33
  • 6
    Why is that everyone is answering: "Use final" when the question it self says "Other than final..." I think they are right, but the point is, that is not the question. I guess we are getting use to "subjective & argumentative" questions that we are missing the point. – OscarRyz Jan 16 '09 at 17:34
  • The question is very clear, and the answer are not real answer, and yet getting upvoted. Shouldn't we use http://stackoverflow.com/questions/318503/comments-for-comments-answers-for-answers-is-it-that-hard :) – OscarRyz Jan 16 '09 at 17:35
  • is this a interview/classroom questions? – Miserable Variable Jan 16 '09 at 17:35
  • There are plenty of valid reasons for avoiding final, mostly when you are extending a framework who's methods and constructors don't allow final. App server extensions come to mind. – gyleg5 Jan 02 '23 at 17:24

8 Answers8

34

A comment

//Do not inherit please
vava
  • 24,851
  • 11
  • 64
  • 79
  • 1
    I actually believe that's the best solution ever. You could even describe why it shouldn't to be inherited from. – vava Jan 16 '09 at 17:09
24

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)

Michael Myers
  • 188,989
  • 46
  • 291
  • 292
Peter Štibraný
  • 32,463
  • 16
  • 90
  • 116
9
  • 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");
    }
    
Jason Plank
  • 2,336
  • 5
  • 31
  • 40
Landon Kuhn
  • 76,451
  • 45
  • 104
  • 130
  • 1
    The comment idea really does not make much sense. A JavaDoc comment makes a lot more sense, but is still not foolproof. – eleven81 Jan 16 '09 at 17:29
  • [Java doesn't prevent sub-classing of class with private constructors](https://stackoverflow.com/a/16662680/2114786) – O.Badr Oct 12 '21 at 22:20
7

Final was created to solve this problem.

NotMe
  • 87,343
  • 27
  • 171
  • 245
4

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 { ... }
}
Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
3

Using final is the canonical way.

public final class FinalClass {
  // Class definition
}

If you want to prevent individual methods from being overridden, you can declare them as final instead. (I'm just guessing here, as to why you would want to avoid making the whole class final.)

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
1

I'd have to say it's typically bad form. Though there are almost always cases where something is valid, I'd have to saying stopping inheritance in an OO world is normally not a good idea. Read up on the Open-Closed Principle and here. Protect your functionality but don't make it impossible for the guy who comes in and supports it...

Mark G
  • 368
  • 1
  • 6
  • 3
    Inheritance is way overrated. Unless you design your class for subclassing, you better avoid it. – Peter Štibraný Jan 16 '09 at 17:13
  • +1, I'm betting that Uncle Bob Martin knows more about OO than just about anyone here. – jcollum Jan 16 '09 at 17:15
  • 1
    +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. – Jon Skeet Jan 16 '09 at 17:15
  • 1
    "Design and document for inheritance or else prohibit it." -- Josh Bloch, Effective Java Item 17 – Michael Myers Jan 16 '09 at 17:17
  • 1
    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... – Mark G Jan 16 '09 at 17:18
  • @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. – Jon Skeet Jan 16 '09 at 17:54
  • 1
    @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' – Mark G Jan 16 '09 at 18:35
0

Without using a final class, you can basically make all the constructors private:

public class A {
    private A() {} //Overriding default constructor of Java
}

Which although will also make this class abstract-ish by disallowing creating an object of this class, yet as any inheritance requires super(); in the constructor, and because the constructor is private, a compilation error will be the maximum you can get when one tries to inherit that class. Yet, I would recommend using final instead as it is less code and includes the option of creating objects.