views:

441

answers:

7

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

+10  A: 

A comment

//Do not inherit please
vava
+1 for creativity.
Chris Lively
+1 for being nice.
Otávio Décio
I actually believe that's the best solution ever. You could even describe why it shouldn't to be inherited from.
vava
Too bad that they might never see the source code.
eleven81
Yes, clearly it should be a javadoc comment :-)
Nick Fortescue
+6  A: 

Final was created to solve this problem.

Chris Lively
+1  A: 

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
Inheritance is way overrated. Unless you design your class for subclassing, you better avoid it.
Peter Štibraný
+1, I'm betting that Uncle Bob Martin knows more about OO than just about anyone here.
jcollum
+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
"Design and document for inheritance or else prohibit it." -- Josh Bloch, Effective Java Item 17
Michael Myers
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
@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
@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
+12  A: 

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)

Peter Štibraný
Rats, I was just going to post the exception one myself.
Michael Myers
Except if the finalize method is overriden, the instance can be recovered.
Tom Hawtin - tackline
@Tom: two wrongs make an evil!
Michael Myers
+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.
Outlaw Programmer
@Tom: this might break the no two security managers rule
Joshua
This doesn't prevent you from overriding the constructor...
Chris Lively
@Chris Lively: Constructor from super class must always be called. You can 'override' constructor (there is no such thing as overriding constructor though, as constructor is not inherited), but you cannot 'skip' constructor from super class.
Peter Štibraný
+3  A: 

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
Reasons similar to java.lang.String, I'd guess.
duffymo
String is final.
Bill the Lizard
+1  A: 
  • 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"); }

landon9720
The comment idea really does not make much sense. A JavaDoc comment makes a lot more sense, but is still not foolproof.
eleven81
+3  A: 

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