Am I the only one who's seeing "sealed" classes as an unfortunate development?
I can't count how many times I had to resolve to using PowerMock and hacking bytecode just to mock something in one of the libraries I use because it's ingenious author "final"-ed the whole API surface of the library (and bits of the implementation usually).
Now this gives even greater tool to people who love to lock everything up and think that they know better than me what I need.
IMO sealing for classes is unnecessary, so long as methods are opt-in for overriding (e.g. as in C++ or C#, where you need to explicitly say "virtual"). If you can't override anything in a derived class, how can you break invariants?
Yeah - personally I think languages should allow a lot of constraints like sealed classes (it makes your intent clear, and can allow extra optimizations, that's good!), but highly-risky "escape hatches" need to exist because they solve real problems.
"Fork and modify" is a very capable alternative, but it's far, far, far more costly than "monkey-patch this one time issue that'll be fixed next week". And some languages make it extremely painful to achieve, often requiring significant code rewriting, and which sometimes make contributing back to the source-library significantly harder. And when such hacks hang around longer for a week... well, sometimes that's fine, sometimes it's not, and the library author is not the one who should be making that decision. It's my program, it should do what I tell it to do.
I think you're thinking of `record` classes? Sealed classes are about constraining inheriting or implementing to only approved types - using sealed is pointless without overriding of some kind. Unlike in some other languages, where sealed is closer to java's final classes, i.e. stopping inheritance.
The only thing I can find on Scala with "sealed" is for exhaustive pattern-matching on types, which 1) broadly matches Java, and 2) has nothing to do with data-only objects at all. Sealing and methods are entirely orthogonal.
Don't think of it as a less powerful class, think of it as a more powerful enum. At least that's how it's meant to be used. It's a good feature in other languages, and like you said, "final" already exists, so you're no worse off on that front.
I can't count how many times I had to resolve to using PowerMock and hacking bytecode just to mock something in one of the libraries I use because it's ingenious author "final"-ed the whole API surface of the library (and bits of the implementation usually).
Now this gives even greater tool to people who love to lock everything up and think that they know better than me what I need.