I use the Scanner class for reading multiple similar files. I would like to extend it to make sure they all use the same delimiter and I can also add methods like skipUntilYouFind(String thisHere) that all valid for them all.
I can make a utility-class that contain them, or embed the Scanner Class as a variable inside another class but this is more cumbersome.
I have found some reasons to declare a class final, but why is it done here?
Probably because extending it and overwriting some of it's methods would probably break it. And making it easier to overwrite methods would expose to much of the inner workings, so if in the future they decide to change those (for performance or some other reasons), it would be harder for them to change the class without breaking all the classes that extend it.
For example, consider the following method in the class:
public boolean nextBoolean() {
clearCaches();
return Boolean.parseBoolean(next(boolPattern()));
}
Say you want to overwrite this because you want to make 'awesome' evaluate to a 'true' boolean (for whatever reason). If you overwrite it, you can't call super.nextBoolean(), since that would consume the next token using the default logic. But if you don't call super.nextBoolean(), clearCaches() won't be called, possibly breaking the other not overwritten methods. You can't call clearCaches() because it's private. If they made it protected, but then realized that it's causing a performance problem, and wanted a new implementation that doesn't clear caches anymore, then they might break your overwritten implementation which would still be calling that.
So basically it's so they can easily change the hidden parts inside the class, which are quite complex, and protecting you from making a broken child class (or a class that could be easily be broken).
I suppose it is due to security reasons. This class reads user input, so that someone with bad intentions could extend it, modify it's behavior and you'd be screwed. If it is final, it is not that easy for the bad guy, because if he makes his own type of Scanner (not java.util.Scanner), the principles of Polymorphism would be broken. See the bad guy can be smart enough to write a bot/script which does this automatically on remote servers... He can even do it by dynamic classloading in compiled application.
I think that the link you provided explains it all.
In your case it seems like you should prefer composition instead of inheritance anyway. You are creating a utility that has some predefined behavior, and that can hide some (or all) of the details of the Scanner class.
I've seen many implementations that used inheritance in order to change a behavior. The end result was usually a monolithic design, and in some cases, a broken contract, and/or broken behavior.
Related
I haven't found any clear articles on this, but I was wondering about why polymorphism is the recommended design pattern over exhaustive switch case / pattern matching. I ask this because I've gotten a lot of heat from experienced developers for not using polymorphic classes, and it's been troubling me. I've personally had a terrible time with polymorphism and a wonderful time with switch cases, the reduction in abstractions and indirection makes readability of the code so much easier in my opinion. This is in direct contrast with books like "clean code" which are typically seen as industry standards.
Note: I use TypeScript, so the following examples may not apply in other languages, but I think the principle generally applies as long as you have exhaustive pattern matching / switch cases.
List the options
If you want to know what the possible values of an action, with an enum, switch case, this is trivial. For classes this requires some reflection magic
// definitely two actions here, I could even loop over them programmatically with basic primitives
enum Action {
A = 'a',
B = 'b',
}
Following the code
Dependency injection and abstract classes mean that jump to definition will never go where you want
function doLetterThing(myEnum: Action) {
switch (myEnum) {
case Action.A:
return;
case Action.B;
return;
default:
exhaustiveCheck(myEnum);
}
}
versus
function doLetterThing(action: BaseAction) {
action.doAction();
}
If I jump to definition for BaseAction or doAction I will end up on the abstract class, which doesn't help me debug the function or the implementation. If you have a dependency injection pattern with only a single class, this means that you can "guess" by going to the main class / function and looking for how "BaseAction" is instantiated and following that type to the place and scrolling to find the implementation. This seems generally like a bad UX for a developer though.
(small note about whether dependency injection is good, traits seem to do a good enough job in cases where they are necessary (though either done prematurely as a rule rather than as a necessity seems to lead to more difficult to follow code))
Write less code
This depends, but if have to define an extra abstract class for your base type, plus override all the function types, how is that less code than single line switch cases? With good types here if you add an option to the enum, your type checker will flag all the places you need to handle this which will usually involve adding 1 line each for the case and 1+ line for implementation. Compare this with polymorphic classes which you need to define a new class, which needs the new function syntax with the correct params and the opening and closing parens. In most cases, switch cases have less code and less lines.
Colocation
Everything for a type is in one place which is nice, but generally whenever I implement a function like this is I look for a similarly implemented function. With a switch case, it's extremely adjacent, with a derived class I would need to find and locate in another file or directory.
If I implemented a feature change such as trimming spaces off the ends of a string for one type, I would need to open all the class files to make sure if they implement something similar that it is implemented correctly in all of them. And if I forget, I might have different behaviour for different types without knowing. With a switch the co location makes this extremely obvious (though not foolproof)
Conclusion
Am I missing something? It doesn't make sense that we have these clear design principles that I basically can only find affirmative articles about but don't see any clear benefits, and serious downsides compared to some basic pattern matching style development
Consider the solid-principles, in particular OCP and DI.
To extend a switch case or enum and add new functionality in the future, you must modify the existing code. Modifying legacy code is risky and expensive. Risky because you may inadvertently introduce regression. Expensive because you have to learn (or re-learn) implementation details, and then re-test the legacy code (which presumably was working before you modified it).
Dependency on concrete implementations creates tight coupling and inhibits modularity. This makes code rigid and fragile, because a change in one place affects many dependents.
In addition, consider scalability. An abstraction supports any number of implementations, many of which are potentially unknown at the time the abstraction is created. A developer needn't understand or care about additional implementations. How many cases can a developer juggle in one switch, 10? 100?
Note this does not mean polymorphism (or OOP) is suitable for every class or application. For example, there are counterpoints in, Should every class implement an interface? When considering extensibility and scalability, there is an assumption that a code base will grow over time. If you're working with a few thousand lines of code, "enterprise-level" standards are going to feel very heavy. Likewise, coupling a few classes together when you only have a few classes won't be very noticeable.
Benefits of good design are realized years down the road when code is able to evolve in new directions.
I think you are missing the point. The main purpose of having a clean code is not to make your life easier while implementing the current feature, rather it makes your life easier in future when you are extending or maintaining the code.
In your example, you may feel implementing your two actions using switch case. But what happens if you need to add more actions in future? Using the abstract class, you can easily create a new action type and the caller doesn't need to be modified. But if you keep using switch case it will be lot more messier, especially for complex cases.
Also, following a better design pattern (DI in this case) will make the code easier to test. When you consider only easy cases, you may not find the usefulness of using proper design patterns. But if you think broader aspect, it really pays off.
"Base class" is against the Clean Code. There should not be a "Base class", not just for bad naming, also for composition over inheritance rule. So from now on, I will assume it is an interface in which other classes implement it, not extend (which is important for my example). First of all, I would like to see your concerns:
Answer for Concerns
This depends, but if have to define an extra abstract class for your
base type, plus override all the function types, how is that less code
than single line switch cases
I think "write less code" should not be character count. Then Ruby or GoLang or even Python beats the Java, obviously does not it? So I would not count the lines, parenthesis etc. instead code that you should test/maintain.
Everything for a type is in one place which is nice, but generally
whenever I implement a function like this is I look for a similarly
implemented function.
If "look for a similarly" means, having implementation together makes copy some parts from the similar function then we also have some clue here for refactoring. Having Implementation class differently has its own reason; their implementation is completely different. They may follow some pattern, lets see from Communication perspective; If we have Letter and Phone implementations, we should not need to look their implementation to implement one of them. So your assumption is wrong here, if you look to their code to implement new feature then your interface does not guide you for the new feature. Let's be more specific;
interface Communication {
sendMessage()
}
Letter implements Communication {
sendMessage() {
// get receiver
// get sender
// set message
// send message
}
}
Now we need Phone, so if we go to Letter implementation to get and idea to how to implement Phone then our interface does not enough for us to guide our implementation. Technically Phone and Letter is different to send a message. Then we need a Design pattern here, maybe Template Pattern? Let's see;
interface Communication {
default sendMessage() {
getMessageFactory().sendMessage(getSender(), getReceiver(), getBody())
}
getSender()
getReceiver()
getBody()
}
Letter implements Communication {
getSender() { returns sender }
getReceiver() {returns receiver }
getBody() {returns body}
getMessageFactory {returns LetterMessageFactory}
}
Now when we need to implement Phone we don't need to look the details of other implementations. We exactly now what we need to return and also our Communication interface's default method handles how to send the message.
If I implemented a feature change such as trimming spaces off the ends
of a string for one type, I would need to open all the class files to
make sure if they implement something similar that it is implemented
correctly in all of them...
So if there is a "feature change" it should be only its implemented class, not in all classes. You should not change all of the implementations. Or if it is same implementation in all of them, then why each implements it differently? It should be kept as the default method in their interface. Then if feature change required, only default method is changed and you should update your implementation and test in one place.
These are the main points that I wanted to answer your concerns. But I think the main point is you don't get the benefit. I was also struggling before I work on a big project that other teams need to extend my features. I will divide benefits to topics with extreme examples which may be more helpful to understand:
Easy to read
Normally when you see a function, you should not feel to go its implementation to understand what is happening there. It should be self-explanatory. Based on this fact; action.doAction(); -> or lets say communication.sendMessage() if they implement Communicate interface. I don't need to go for its base class, search for implementations etc. for debugging. Even implementing class is "Letter" or "Phone" I know that they send message, I don't need their implementation details. So I don't want to see all implemented classes like in your example "switch Letter; Phone.." etc. In your example doLetterThing responsible for one thing (doAction), since all of them do same thing, then why you are showing your developer all these cases?. They are just making the code harder to read.
Easy to extend
Imagine that you are extending a big project where you don't have an access to their source(I want to give extreme example to show its benefit easier). In the java world, I can say you are implementing SPI (Service Provider Interface). I can show you 2 example for this, https://github.com/apereo/cas and https://github.com/keycloak/keycloak where you can see that interface and implementations are separated and you just implement new behavior when it is required, no need to touch the original source. Why this is important? Imagine the following scenario again;
Let's suppose that Keycloak calls communication.sendMessage(). They don't know implementations in build time. If you extend Keycloak in this case, you can have your own class that implements Communication interface, let's say "Computer". Know if you have your SPI in the classpath, Keycloak reads it and calls your computer.sendMessage(). We did not touch the source code but extended the capabilities of Message Handler class. We can't achieve this if we coded against switch cases without touching the source.
I am currently developing an API that uses abstract classes with default implementations. While I have done this in the past I have not really thought of the philosophical implications of calls back to base.SomeMethod() in the derived class since the APIs were not intended for public consumption. Since this API is intended to be publicly visible, I am wondering how I should handle calls back into the base class. Is it OK for me to assume that the base call will always happen first or last in the derived implementation and I simply document the assumption for the implementer? Or should the base class calls have no side effects, so it wouldn't matter when the implementer calls the base class? Is there a rule of thumb for this?
Thanks.
IMHO it depends pretty much on the needs of your particular class. If you want to make sure that the base behavior is called (and maybe even in a special order) you can use a template method. I find this pattern as a really elegant way of providing subclasses extension points in a controlled way and I think is better than leaving a comment to the developer.
The obvious downside is that if you choose badly the hooks, you could be constraining too much the other developer. I remember once or twice having to override a template method because the hooks didn't allow me to perform the behavior I needed.
HTH
I understand the differences between them (at least in C#). I know the effects they have on the elements to which they are assigned. What I don't understand is why it is important to implement them - why not have everything Public?
The material I read on the subject usually goes on about how classes and methods shouldn't have unnecessary access to others, but I've yet to come across an example of why/how that would be a bad thing. It seems like a security thing, but I'm the programmer; I create the methods and define what they will (or will not) do. Why would I spend all the effort to write a function which tried to change a variable it shouldn't, or tried to read information in another class, if that would be bad?
I apologize if this is a dumb question. It's just something I ran into on the first articles I ever read on OOP, and I've never felt like it really clicked.
I'm the programmer is a correct assumption only if you're the only programmer.
In many cases, other programmers work with the first programmer's code. They use it in ways he didn't intend by fiddling with the values of fields they shouldn't, and they create a hack that works, but breaks when the producer of the original code changes it.
OOP is about creating libraries with well-defined contracts. If all your variables are public and accessible to others, then the "contract" theoretically includes every field in the object (and its sub-objects), so it becomes much harder to build a new, different implementation that still honors the original contract.
Also, the more "moving parts" of your object are exposed, the easier it is for a user of your class to manipulate it incorrectly.
You probably don't need this, but here's an example I consider amusing:
Say you sell a car with no hood over the engine compartment. Come nighttime, the driver turns on the lights. He gets to his destination, gets out of the car and then remembers he left the light on. He's too lazy to unlock the car's door, so he pulls the wire to the lights out from where it's attached to the battery. This works fine - the light is out. However, because he didn't use the intended mechanism, he finds himself with a problem next time he's driving in the dark.
Living in the USA (go ahead, downvote me!), he refuses to take responsibility for his incorrect use of the car's innards, and sues you, the manufacturer for creating a product that's unsafe to drive in the dark because the lights can't be reliably turned on after having been turned off.
This is why all cars have hoods over their engine compartments :)
A more serious example: You create a Fraction class, with a numerator and denominator field and a bunch of methods to manipulate fractions. Your constructor doesn't let its caller create a fraction with a 0 denominator, but since your fields are public, it's easy for a user to set the denominator of an existing (valid) fraction to 0, and hilarity ensues.
First, nothing in the language forces you to use access modifiers - you are free to make everything public in your class if you wish. However, there are some compelling reasons for using them. Here's my perspective.
Hiding the internals of how your class operates allows you to protect that class from unintended uses. While you may be the creator of the class, in many cases you will not be the only consumer - or even maintainer. Hiding internal state protects the class for people who may not understand its workings as well as you. Making everything public creates the temptation to "tweak" the internal state or internal behavior when the class isn't acting the way you may want - rather than actually correcting the public interface of internal implementation. This is the road to ruin.
Hiding internals helps to de-clutter the namespace, and allows tools like Intellisense to display only the relevant and meaningful methods/properties/fields. Don't discount tools like Intellisense - they are a powerful means for developers to quickly identify what they can do with your class.
Hiding internals allows you to structure an interface appropriate for the problem the class is solving. Exposing all of the internals (which often substantially outnumber the exposed interface) makes it hard to later understand what the class is trying to solve.
Hiding internals allows you to focus your testing on the appropriate portion - the public interface. When all methods/properties of a class are public, the number of permutations you must potentially test increases significantly - since any particular call path becomes possible.
Hiding internals helps you control (enforce) the call paths through your class. This makes it easier to ensure that your consumers understand what your class can be asked to do - and when. Typically, there are only a few paths through your code that are meaningful and useful. Allowing a consumer to take any path makes it more likely that they will not get meaningful results - and will interpret that as your code being buggy. Limiting how your consumers can use your class actually frees them to use it correctly.
Hiding the internal implementation frees you to change it with the knowledge that it will not adversely impact consumers of your class - so long as your public interface remains unchanged. If you decide to use a dictionary rather than a list internally - no one should care. But if you made all the internals of your class available, someone could write code that depends on the fact that your internally use a list. Imagine having to change all of the consumers when you want to change such choices about your implementation. The golden rule is: consumers of a class should not care how the class does what it does.
It is primarily a hiding and sharing thing. You may produce and use all your own code, but other people provide libraries, etc. to be used more widely.
Making things non-public allows you to explicitly define the external interface of your class. The non-public stuff is not part of the external interface, which means you can change anything you want internally without affecting anyone using the external interface,
You only want to expose the API and keep everything else hidden. Why?
Ok lets assume you want to make an awesome Matrix library so you make
class Matrix {
public Object[][] data //data your matrix storages
...
public Object[] getRow()
}
By default any other programmer that use your library will want to maximize the speed of his program by tapping into the underlying structure.
//Someone else's function
Object one() {data[0][0]}
Now, you discover that using list to emulate the matrix will increase performance so you change data from
Object[][] data => Object[] data
causes Object one() to break. In other words by changing your implementation you broke backward compatibility :-(
By encapsulating you divide internal implementation from external interface (achieved with a private modifier).
That way you can change implementation as much as possible without breaking backward compatibility :D Profit!!!
Of course if you are the only programmer that is ever going to modify or use that class you might as well as keep it public.
Note: There are other major benefits for encapsulating your stuff, this is just one of many. See Encapsulation for more details
I think the best reason for this is to provide layers of abstraction on your code.
As your application grows, you will need to have your objects interacting with other objects. Having publicly modifiable fields makes it harder to wrap your head around your entire application.
Limiting what you make public on your classes makes it easier to abstract your design so you can understand each layer of your code.
For some classes, it may seem ridiculous to have private members, with a bunch of methods that just set and get those values. The reason for it is that let's say you have a class where the members are public and directly accessible:
class A
{
public int i;
....
}
And now you go on using that in a bunch of code you wrote. Now after writing a bunch of code that directly accesses i and now you realize that i should have some constraints on it, like i should always be >= 0 and less than 100 (for argument's sake).
Now, you could go through all of your code where you used i and check for this constraint, but you could just add a public setI method that would do it for you:
class A
{
private int i;
public int I
{
get {return i;}
set
{
if (value >= 0 && value < 100)
i = value;
else
throw some exception...
}
}
}
This hides all of that error checking. While the example is trite, situations like these come up quite often.
It is not related to security at all.
Access modifers and scope are all about structure, layers, organization, and communication.
If you are the only programmer, it is probably fine until you have so much code even you can't remember. At that point, it's just like a team environment - the access modifiers and the structure of the code guide you to stay within the architecture.
Why would anyone want to mark a class as final or sealed?
According to Wikipedia, "Sealed classes are primarily used to prevent derivation. They add another level of strictness during compile-time, improve memory usage, and trigger certain optimizations that improve run-time efficiency."
Also, from Patrick Smacchia's blog:
Versioning: When a class is originally sealed, it can change to unsealed in the future without breaking compatibility. (…)
Performance: (…) if the JIT compiler sees a call to a virtual method using a sealed types, the JIT compiler can produce more efficient code by calling the method non-virtually.(…)
Security and Predictability: A class must protect its own state and not allow itself to ever become corrupted. When a class is unsealed, a derived class can access and manipulate the base class’s state if any data fields or methods that internally manipulate fields are accessible and not private.(…)
Those are all pretty good reasons - I actually wasn't aware of the performance benefit implications until I looked it up just now :)
The versioning and security points seem like a huge benefit in terms of code confidence, which is very well justified on any kind of large project. It's no drop-in for unit testing, of course, but it would help.
Because creating a type for inheritance is much harder work than most folks think. It is best to mark all types this way by default as this will prevent others from inheriting from a type that was never intended to be extended.
Whether or not a type should be extended is a decision of the developer who created it, not the developer who comes along later and wants to extend it.
Joshua Bloch in his book Effective Java talks about it. He says "document for inheritance or disallow it".
The point is that class is sort of a contract between author and client. Allowing client to inherit from base class makes this contract much more strict. If you are going to inherit from it, you most likely are going to override some methods, otherwise you can replace inheritance with composition. Which methods are allowed to be overridden, and what you have to do implementing them - should be documented, or your code can lead to unpredictable results. As far as I remember, he shows such example - here is a collection class with methods
public interface Collection<E> extends Iterable<E> {
...
boolean add(E e);
boolean addAll(Collection<? extends E> c);
...
}
There is some implementation, i.e. ArrayList. Now you want to inherit from it and override some methods, so it prints to console a message when element is added. Now, do you need to override both add and addAll, or only add? It depends on how addAll is implemented - does it work with internal state directly (as ArrayList does) or calls add (as AbstractCollection does). Or may be there is addInternal, which is called by both add and addAll. There were no such questions until you decided to inherit from this class. If you just use it - it does not bother you. So the author of the class has to document it, if he wants you to inherit from his class.
And what if he wants to change the implementation in the future? If his class is only used, never inherited from, nothing stops him from changing implementation to more efficient. Now, if you inherited from that class, looked at source and found that addAll calls add, you override only add. Later author changes implementation so addAll no longer calls add - your program is broken, message is not printed when addAll is called. Or you looked at source and found that addAll does not call add, so you override add and addAll. Now author changes implementation, so addAll calls add - your program is broken again, when addAll is called message is printed twice for each element.
So - if you want your class to be inherited from, you need to document how. If you think that you may need to change something in the future that may break some subclasses - you need to think how to avoid it. By letting your clients inherit from your class you expose much more of internal implementation details that you do when you just let them use your class - you expose internal workflow, that is often subject to changes in future versions.
If you expose some details and clients rely on them - you no longer can change them. If it is ok with you, or you documented what can and what can not be overriden - that's fine. Sometimes you just don't want it. Sometimes you just want to say - "just use this class, never inherit from it, because I want a freedom to change internal implementation details".
So basically comment "Because the class doesn't want to have any children and we should respect it's wishes" is correct.
So, someone wants to mark a class as final/sealed, when he thinks that possible implementation details changes are more valuable than inheritance. There are other ways to achieve results similar to inheritance.
What can be reasons to prevent a class from being inherited? (e.g. using sealed on a c# class)
Right now I can't think of any.
Because writing classes to be substitutably extended is damn hard and requires you to make accurate predictions of how future users will want to extend what you've written.
Sealing your class forces them to use composition, which is much more robust.
How about if you are not sure about the interface yet and don't want any other code depending on the present interface? [That's off the top of my head, but I'd be interested in other reasons as well!]
Edit:
A bit of googling gave the following:
http://codebetter.com/blogs/patricksmacchia/archive/2008/01/05/rambling-on-the-sealed-keyword.aspx
Quoting:
There are three reasons why a sealed class is better than an unsealed class:
Versioning: When a class is originally sealed, it can change to unsealed in the future without breaking compatibility. (…)
Performance: (…) if the JIT compiler sees a call to a virtual method using a sealed types, the JIT compiler can produce more efficient code by calling the method non-virtually.(…)
Security and Predictability: A class must protect its own state and not allow itself to ever become corrupted. When a class is unsealed, a derived class can access and manipulate the base class’s state if any data fields or methods that internally manipulate fields are accessible and not private.(…)
I want to give you this message from "Code Complete":
Inheritance - subclasses - tends to
work against the primary technical
imperative you have as a programmer,
which is to manage complexity.For the sake of controlling complexity, you should maintain a heavy bias against inheritance.
The only legitimate use of inheritance is to define a particular case of a base class like, for example, when inherit from Shape to derive Circle. To check this look at the relation in opposite direction: is a Shape a generalization of Circle? If the answer is yes then it is ok to use inheritance.
So if you have a class for which there can not be any particular cases that specialize its behavior it should be sealed.
Also due to LSP (Liskov Substitution Principle) one can use derived class where base class is expected and this is actually imposes the greatest impact from use of inheritance: code using base class may be given an inherited class and it still has to work as expected. In order to protect external code when there is no obvious need for subclasses you seal the class and its clients can rely that its behavior will not be changed. Otherwise external code needs to be explicitly designed to expect possible changes in behavior in subclasses.
A more concrete example would be Singleton pattern. You need to seal singleton to ensure one can not break the "singletonness".
This may not apply to your code, but a lot of classes within the .NET framework are sealed purposely so that no one tries to create a sub-class.
There are certain situations where the internals are complex and require certain things to be controlled very specifically so the designer decided no one should inherit the class so that no one accidentally breaks functionality by using something in the wrong way.
#jjnguy
Another user may want to re-use your code by sub-classing your class. I don't see a reason to stop this.
If they want to use the functionality of my class they can achieve that with containment, and they will have much less brittle code as a result.
Composition seems to be often overlooked; all too often people want to jump on the inheritance bandwagon. They should not! Substitutability is difficult. Default to composition; you'll thank me in the long run.
I am in agreement with jjnguy... I think the reasons to seal a class are few and far between. Quite the contrary, I have been in the situation more than once where I want to extend a class, but couldn't because it was sealed.
As a perfect example, I was recently creating a small package (Java, not C#, but same principles) to wrap functionality around the memcached tool. I wanted an interface so in tests I could mock away the memcached client API I was using, and also so we could switch clients if the need arose (there are 2 clients listed on the memcached homepage). Additionally, I wanted to have the opportunity to replace the functionality altogether if the need or desire arose (such as if the memcached servers are down for some reason, we could potentially hot swap with a local cache implementation instead).
I exposed a minimal interface to interact with the client API, and it would have been awesome to extend the client API class and then just add an implements clause with my new interface. The methods that I had in the interface that matched the actual interface would then need no further details and so I wouldn't have to explicitly implement them. However, the class was sealed, so I had to instead proxy calls to an internal reference to this class. The result: more work and a lot more code for no real good reason.
That said, I think there are potential times when you might want to make a class sealed... and the best thing I can think of is an API that you will invoke directly, but allow clients to implement. For example, a game where you can program against the game... if your classes were not sealed, then the players who are adding features could potentially exploit the API to their advantage. This is a very narrow case though, and I think any time you have full control over the codebase, there really is little if any reason to make a class sealed.
This is one reason I really like the Ruby programming language... even the core classes are open, not just to extend but to ADD AND CHANGE functionality dynamically, TO THE CLASS ITSELF! It's called monkeypatching and can be a nightmare if abused, but it's damn fun to play with!
From an object-oriented perspective, sealing a class clearly documents the author's intent without the need for comments. When I seal a class I am trying to say that this class was designed to encapsulate some specific piece of knowledge or some specific service. It was not meant to be enhanced or subclassed further.
This goes well with the Template Method design pattern. I have an interface that says "I perform this service." I then have a class that implements that interface. But, what if performing that service relies on context that the base class doesn't know about (and shouldn't know about)? What happens is that the base class provides virtual methods, which are either protected or private, and these virtual methods are the hooks for subclasses to provide the piece of information or action that the base class does not know and cannot know. Meanwhile, the base class can contain code that is common for all the child classes. These subclasses would be sealed because they are meant to accomplish that one and only one concrete implementation of the service.
Can you make the argument that these subclasses should be further subclassed to enhance them? I would say no because if that subclass couldn't get the job done in the first place then it should never have derived from the base class. If you don't like it then you have the original interface, go write your own implementation class.
Sealing these subclasses also discourages deep levels of inheritence, which works well for GUI frameworks but works poorly for business logic layers.
Because you always want to be handed a reference to the class and not to a derived one for various reasons:
i. invariants that you have in some other part of your code
ii. security
etc
Also, because it's a safe bet with regards to backward compatibility - you'll never be able to close that class for inheritance if it's release unsealed.
Or maybe you didn't have enough time to test the interface that the class exposes to be sure that you can allow others to inherit from it.
Or maybe there's no point (that you see now) in having a subclass.
Or you don't want bug reports when people try to subclass and don't manage to get all the nitty-gritty details - cut support costs.
Sometimes your class interface just isn't meant to be inheirited. The public interface just isn't virtual and while someone could override the functionality that's in place it would just be wrong. Yes in general they shouldn't override the public interface, but you can insure that they don't by making the class non-inheritable.
The example I can think of right now are customized contained classes with deep clones in .Net. If you inherit from them you lose the deep clone ability.[I'm kind of fuzzy on this example, it's been a while since I worked with IClonable] If you have a true singelton class, you probably don't want inherited forms of it around, and a data persistence layer is not normally place you want a lot of inheritance.
Not everything that's important in a class is asserted easily in code. There can be semantics and relationships present that are easily broken by inheriting and overriding methods. Overriding one method at a time is an easy way to do this. You design a class/object as a single meaningful entity and then someone comes along and thinks if a method or two were 'better' it would do no harm. That may or may not be true. Maybe you can correctly separate all methods between private and not private or virtual and not virtual but that still may not be enough. Demanding inheritance of all classes also puts a huge additional burden on the original developer to foresee all the ways an inheriting class could screw things up.
I don't know of a perfect solution. I'm sympathetic to preventing inheritance but that's also a problem because it hinders unit testing.
I exposed a minimal interface to interact with the client API, and it would have been awesome to extend the client API class and then just add an implements clause with my new interface. The methods that I had in the interface that matched the actual interface would then need no further details and so I wouldn't have to explicitly implement them. However, the class was sealed, so I had to instead proxy calls to an internal reference to this class. The result: more work and a lot more code for no real good reason.
Well, there is a reason: your code is now somewhat insulated from changes to the memcached interface.
Performance: (…) if the JIT compiler sees a call to a virtual method using a sealed types, the JIT compiler can produce more efficient code by calling the method non-virtually.(…)
That's a great reason indeed. Thus, for performance-critical classes, sealed and friends make sense.
All the other reasons I've seen mentioned so far boil down to "nobody touches my class!". If you're worried someone might misunderstand its internals, you did a poor job documenting it. You can't possibly know that there's nothing useful to add to your class, or that you already know every imaginable use case for it. Even if you're right and the other developer shouldn't have used your class to solve their problem, using a keyword isn't a great way of preventing such a mistake. Documentation is. If they ignore the documentation, their loss.
Most of answers (when abstracted) state that sealed/finalized classes are tool to protect other programmers against potential mistakes. There is a blurry line between meaningful protection and pointless restriction. But as long as programmer is the one who is expected to understand the program, I see no hardly any reasons to restrict him from reusing parts of a class. Most of you talk about classes. But it's all about objects!
In his first post, DrPizza claims that designing inheritable class means anticipating possible extensions. Do I get it right that you think that class should be inheritable only if it's likely to be extended well? Looks as if you were used to design software from the most abstract classes. Allow me a brief explanation of how do I think when designing:
Starting from the very concrete objects, I find characteristics and [thus] functionality that they have in common and I abstract it to superclass of those particular objects. This is a way to reduce code duplicity.
Unless developing some specific product such as a framework, I should care about my code, not others (virtual) code. The fact that others might find it useful to reuse my code is a nice bonus, not my primary goal. If they decide to do so, it's their responsibility to ensure validity of extensions. This applies team-wide. Up-front design is crucial to productivity.
Getting back to my idea: Your objects should primarily serve your purposes, not some possible shoulda/woulda/coulda functionality of their subtypes. Your goal is to solve given problem. Object oriented languages uses fact that many problems (or more likely their subproblems) are similar and therefore existing code can be used to accelerate further development.
Sealing a class forces people who could possibly take advantage of existing code WITHOUT ACTUALLY MODIFYING YOUR PRODUCT to reinvent the wheel. (This is a crucial idea of my thesis: Inheriting a class doesn't modify it! Which seems quite pedestrian and obvious, but it's being commonly ignored).
People are often scared that their "open" classes will be twisted to something that can not substitute its ascendants. So what? Why should you care? No tool can prevent bad programmer from creating bad software!
I'm not trying to denote inheritable classes as the ultimately correct way of designing, consider this more like an explanation of my inclination to inheritable classes. That's the beauty of programming - virtually infinite set of correct solutions, each with its own cons and pros. Your comments and arguments are welcome.
And finally, my answer to the original question: I'd finalize a class to let others know that I consider the class a leaf of the hierarchical class tree and I see absolutely no possibility that it could become a parent node. (And if anyone thinks that it actually could, then either I was wrong or they don't get me).