This is a rather basic OO question, but one that's been bugging me for some time.
I tend to avoid using the 'private' visibility modifier for my fields and methods in favor of protected.
This is because, generally, I don't see any use in hiding the implementation between base class and child class, except when I want to set specific guidelines for the extension of my classes (i.e. in frameworks). For the majority of cases I think trying to limit how my class will be extended either by me or by other users is not beneficial.
But, for the majority of people, the private modifier is usually the default choice when defining a non-public field/method.
So, can you list use cases for private? Is there a major reason for always using private? Or do you also think it's overused?
There is some consensus that one should prefer composition over inheritance in OOP. There are several reasons for this (google if you're interested), but the main part is that:
inheritance is seldom the best tool and is not as flexible as other solutions
the protected members/fields form an interface towards your subclasses
interfaces (and assumptions about their future use) are tricky to get right and document properly
Therefore, if you choose to make your class inheritable, you should do so conciously and with all the pros and cons in mind.
Hence, it's better not to make the class inheritable and instead make sure it's as flexible as possible (and no more) by using other means.
This is mostly obvious in larger frameworks where your class's usage is beyond your control. For your own little app, you won't notice this as much, but it (inheritance-by-default) will bite you in the behind sooner or later if you're not careful.
Alternatives
Composition means that you'd expose customizability through explicit (fully abstract) interfaces (virtual or template-based).
So, instead of having an Vehicle base class with a virtual drive() function (along with everything else, such as an integer for price, etc.), you'd have a Vehicle class taking a Motor interface object, and that Motor interface only exposes the drive() function. Now you can add and re-use any sort of motor anywhere (more or less. :).
There are two situations where it matters whether a member is protected or private:
If a derived class could benefit from using a member, making the member `protected` would allow it to do so, while making it `private` would deny it that benefit.
If a future version of the base class could benefit by not having the member behave as it does in the present version, making the member `private` would allow that future version to change the behavior (or eliminate the member entirely), while making it `protected` would require all future versions of the class to keep the same behavior, thus denying them the benefit that could be reaped from changing it.
If one can imagine a realistic scenario where a derived class might benefit from being able to access the member, and cannot imagine a scenario where the base class might benefit from changing its behavior, then the member should be protected [assuming, of course, that it shouldn't be public]. If one cannot imagine a scenario where a derived class would get much benefit from accessing the member directly, but one can imagine scenarios where a future version of the base class might benefit by changing it, then it should be private. Those cases are pretty clear and straightforward.
If there isn't any plausible scenario where the base class would benefit from changing the member, I would suggest that one should lean toward making it protected. Some would say the "YAGNI" (You Ain't Gonna Need It) principle favors private, but I disagree. If you're is expecting others to inherit the class, making a member private doesn't assume "YAGNI", but rather "HAGNI" (He's Not Gonna Need It). Unless "you" are going to need to change the behavior of the item in a future version of the class, "you" ain't gonna need it to be private. By contrast, in many cases you'll have no way of predicting what consumers of your class might need. That doesn't mean one should make members protected without first trying to identify ways one might benefit from changing them, since YAGNI isn't really applicable to either decision. YAGNI applies in cases where it will be possible to deal with a future need if and when it is encountered, so there's no need to deal with it now. A decision to make a member of a class which is given to other programmers private or protected implies a decision as to which type of potential future need will be provided for, and will make it difficult to provide for the other.
Sometimes both scenarios will be plausible, in which case it may be helpful to offer two classes--one of which exposes the members in question and a class derived from that which does not (there's no standard idiomatic was for a derived class to hide members inherited from its parent, though declaring new members which have the same names but no compilable functionality and are marked with an Obsolete attribute would have that effect). As an example of the trade-offs involved, consider List<T>. If the type exposed the backing array as a protected member, it would be possible to define a derived type CompareExchangeableList<T> where T:Class which included a member T CompareExchangeItem(index, T T newValue, T oldvalue) which would return Interlocked.CompareExchange(_backingArray[index], newValue, oldValue); such a type could be used by any code which expected a List<T>, but code which knew the instance was a CompareExchangeableList<T> could use the CompareExchangeItem on it. Unfortunately, because List<T> does not expose the backing array to derived classes, it is impossible to define a type which allows CompareExchange on list items but which would still be useable by code expecting a List<T>.
Still, that's not to imply that exposing the backing array would have been completely without cost; even though all extant implementations of List<T> use a single backing array, Microsoft might implement future versions to use multiple arrays when a list would otherwise grow beyond 84K, so as to avoid the inefficiencies associated with the Large Object Heap. If the backing array was exposed as protected member, it would be impossible to implement such a change without breaking any code that relied upon that member.
Actually, the ideal thing might have been to balance those interests by providing a protected member which, given a list-item index, will return an array segment which contains the indicated item. If there's only one array, the method would always return a reference to that array, with an offset of zero, a starting subscript of zero, and a length equal to the list length. If a future version of List<T> split the array into multiple pieces, the method could allow derived classes to efficiently access segments of the array in ways that would not be possible without such access [e.g. using Array.Copy] but List<T> could change the way it manages its backing store without breaking properly-written derived classes. Improperly-written derived classes could get broken if the base implementation changes, but that's the fault of the derived class, not the base.
I just prefer private than protected in the default case because I'm following the principle to hide as much as possibility and that's why set the visibility as low as possible.
I am reaching here. However, I think that the use of Protected member variables should be made conciously, because you not only plan to inherit, but also because there is a solid reason derived classed shouldn't use the Property Setters/Getters defined on the base class.
In OOP, we "encapsulate" the member fields so that we can excercise control over how they properties the represent are accessed and changed. When we define a getter/setter on our base for a member variable, we are essentially saying that THIS is how I want this variable to be referenced/used.
While there are design-driven exceptions in which one might need to alter the behavior created in the base class getter/setter methods, it seems to me that this would be a decision made after careful consideration of alternatives.
For Example, when I find myself needing to access a member field from a derived class directly, instead of through the getter/setter, I start thinking maybe that particular Property should be defined as abstract, or even moved to the derived class. This depends upon how broad the hierarchy is, and any number of additional considerations. But to me, stepping around the public Property defined on the base class begins to smell.
Of course, in many cases, it "doesn't matter" because we are not implementing anything within the getter/setter beyond access to the variable. But again, if this is the case, the derived class can just as easily access through the getter/setter. This also protects against hard-to-find bugs later, if employed consistently. If the behgavior of the getter/setter for a member field on the base class is changed in some way, and a derived class references the Protected field directly, there is the potential for trouble.
You are on the right track. You make something private, because your implementation is dependant on it not being changed either by a user or descendant.
I default to private and then make a conscious decision about whether and how much of the inner workings I'm going to expose, you seem to work on the basis, that it will be exposed anyway, so get on with it. As long as we both remember to cross all the eyes and dot all the tees, we are good.
Another way to look at it is this.
If you make it private, some one might not be able to do what they want with your implementation.
If you don't make it private, someone may be able to do something you really don't want them to do with your implementation.
I've been programming OOP since C++ in 1993 and Java in 1995. Time and again I've seen a need to augment or revise a class, typically adding extra functionality tightly integrated with the class. The OOP way to do so is to subclass the base class and make the changes in the subclass. For example a base class field originally referred to only elsewhere in the base class is needed for some other action, or some other activity must change a value of the field (or one of the field's contained members). If that field is private in the base class then the subclass cannot access it, cannot extend the functionality. If the field is protected it can do so.
Subclasses have a special relationship to the base class that other classes elsewhere in the class hierarchy don't have: they inherit the base class members. The purpose of inheritance is to access base class members; private thwarts inheritance. How is the base class developer supposed to know that no subclasses will ever need to access a member? In some cases that can be clear, but private should be the exception rather than the rule. Developers subclassing the base class have the base class source code, so their alternative is to revise the base class directly (perhaps just changing private status to protected before subclassing). That's not clean, good practice, but that's what private makes you do.
I am a beginner at OOP but have been around since the first articles in ACM and IEEE. From what I remember, this style of development was more for modelling something. In the real world, things including processes and operations would have "private, protected, and public" elements. So to be true to the object .....
Out side of modelling something, programming is more about solving a problem. The issue of "private, protected, and public" elements is only a concern when it relates to making a reliable solution. As a problem solver, I would not make the mistake of getting cough up in how others are using MY solution to solve their own problems. Now keep in mind that a main reason for the issue of ...., was to allow a place for data checking (i.e., verifying the data is in a valid range and structure before using it in your object).
With that in mind, if your code solves the problem it was designed for, you have done your job. If others need your solution to solve the same or a simular problem - Well, do you really need to control how they do it. I would say, "only if you are getting some benefit for it or you know the weaknesses in your design, so you need to protect some things."
In my idea, if you are using DI (Dependency Injection) in your project and you are using it to inject some interfaces in your class (by constructor) to use them in your code, then they should be protected, cause usually these types of classes are more like services not data keepers.
But if you want to use attributes to save some data in your class, then privates would be better.
Related
After reading about SOLID in a few places, I was having trouble mapping between explanations with different vocabularies and code. To generalize a bit, I created the diagrams below, and I was hoping that people could point out any 'bugs' in my understanding.
Of course, feel free to reuse/remix/redistribute as you'd like!
I think your diagrams look quite nice, but I'm afraid that I couldn't understand them (particularly the interface one), so I'll comment on the text.
It's not really clear to me what you mean by layer, in the Open/closed I thought you might mean interface, but the interface and dependency items suggest you don't mean that.
Open/closed : actually your text from the Liskov item is closer to describing open/closed. If the code is open for extension, we can make use of it (by extending it) to implement new requirements, but by not modifying the existing code (it's closed for modification) we know we wont break any existing code that made use of it.
"Only depend on outer layer" - if this means only depend on an interface not the implementation, then yes, that's an important principle for SOLID code even though it doesn't map directly to any of the 5 letters.
Dependency inversion uses that but goes beyond it. A piece of code can make use of another via its interface and this is has great maintainability benefits over relying on the implementation, but if the calling code still has the responsibility for creating the object (and therefore choosing the class) that implements the interface then it still has a dependency. If we create the concrete object outside the class or method and pass it in as an interface, then the called code no longer depends on the concrete class, just the interface
void SomeFunction()
{
IThing myIthing* = new ConcreteThing();
// code below can use the interface but this function depends on the Concrete class
}
void SomeFunctionDependencyInjectedVersion(IThing myIthing*)
{
// this version should be able to work with any class that implements the IThing interface,
// whether it really can might depend on some of the other SOLID principles
}
Single responsibility : this isn't about classes intersecting, this is about not giving a code more than one responsibility. If you have a function where you can't think of a better name than doSomethingAndSomethingElse this might be a sign its got more than one responsibility and could be better if it was split (the point I'm making is about the "and" in the name even when the "somethings" are better named).
You should try to define that responsibility so that the class can perform it entirely, (although it make may use of other classes that perform sub-responsibilities for it) but at each level of responsibility that a class is defined it should have one clear reason to exist. When it has more than one it can make code harder to understand, and changes to code related to one responsibility can have unwanted side-effects on other responsibilities.
Iterface segregation: Consider a class implementing a collection. The class will implement code to add to the collection or to read from it. We could put all this in one interface, but if we separate it then when we have consuming code that only needs to read and doesn't need to add to the collection then it can use the interface made of the reading methods. This can make the code clearer in that it shows quickly that the code only needs those methods, and, if we've injected the collection by interface we could also use that code with a different source of items that doesn't have the ability to add items
(consider IEnumerable vs ICollection vs IList)
Liskov substitution is all about making sure that objects that inherit from an interface/base class behave in the way that the interface/base class promised to behave. In the strictest interpretation of the original definition they'd need to behave exactly the same, but that's not all that useful. More generally its about behaving in a consistent and expected way, the derived classes may add functionality, but they should be able to do the job of the base objects (they can be substituted for them)
I have common functions, such as syntactic sugar for calling the database, logging or site-wide information such as a look-up tables.
If I put these in a site-wide base class I will have access to them, however it just seems intuitively wrong to use a parent class this way. It would make more sense to use the base class as a 'has a' relationship rather than an 'is a'.
Or perhaps this is good design? Is there any problem doing this?
Parent classes should instantiate some base functionality and a child should instantiate the differentiating code.
IMNSHO, what you are describing is a bastardization of that process.
Ideally you would only want to serializable POCO classes, because they only contain properties and no methods.
Having a baseclass for common functionality might be a good idea, if you place code it in, that will be same in every childpage and if there is no other good place.
For instance you could place Helper-methods inside a baseclass, but that breaks OOP in my opinion.
In my opinion, having a class that derives from System.Web.UI.Page and replaces some logic in the OnInit event or other events is a very good strategy. I've used this approach in various projects, but I limited the code in the baseblass to globalization and logic for memberpages (like redirects to non public pages).
I believe that what you are doing is wrong.
First of all, object should be dedicated to one task. Having db connection handling, logging or look-up tables in the same class seems very ugly, regardless of whether these funcitonalities are inherited or not.
Moreover, the functionalities you described seem like fitting the exact idea of an object, just as described above. So, to answer your question: yes, has-a relationship seems like a much better solution.
In general, I tend to try to put program-wide accessible functions in separate classes. If possible, I try to use static methods. Behind these sometimes are singletons, sometimes there is some kind of queue, and sometimes something entirely different. Still, having one single point of origin for such functionalities the code is very flexible. If static methods are not applicable, especially when there is a need to store some information in such helper class, only then do I instantiate an object for each instance of other class. Even then factory/pool single point of origin static methods are often a good idea.
I just don't know why this is the RULE. and what benifit of this rule?
Could you give me a example that we better follow this rule.
It is also called data hiding which helps to maintain the integrity of the object. It saves the data from misuse and outside interference. The data cannot be accessed directly but access controls can be specified in order to obtain the information. The data or object can be made public or private depending on the needs. The data which is private is not accessible outside the scope of the object. When the data is public it can be accessed by the other parts of the program.
"Preventing users of your class misusing it" is often touted as the reason that encapsulation is so important.
I think that has an implication that you are writing classes for other un-trusted developers to use, which I think is rarely the case. The un-trusted clients argument confuses the issue.
Most of the time the users of your class are "you" and members of your team.
The public methods and properties of your class make up the interface point between your class and the rest of your code. The smaller that interface is the easier it is to use and understand.
The reason you encapsulate is to make the interface for your class as small and succinct as possible.
If your classes are highly cohesive and have small interfaces you can easily "forget" about how they work and focus on another part of your program.
Take the example of a class that makes web requests. It may expose a single public method DownloadFile(url). This class could be extremely complicated but it's simple interface means you can forget about the internals of how it works leaving you more room in your head to focus on the problem you are trying to solve.
The counter example would be a web request class that exposed all it's methods publicly. It make have 20 methods, DownloadBegin, DownloadEnd, ChooseProtocol, etc etc. All of those may be used internally but were never intended to be called externally. In order to use the class you then have to know how it works internally before you can know which methods to call.
One of the virtues of data hiding that gets touted a lot is that it helps to protect your class from misuse. You can't trust the users of your class to do the right thing with it, so you make it impossible to do the wrong thing with it. Most of the time giving a user of your class direct access to any of its members opens up the possibility for that member to be set to some invalid or nonsensical value, or set at the wrong time.
One of the more practical reasons is, you can't change the implementation of a data member. If you have, say, a size member that you make publicly accessible, then later you need to have the class actually do something in response to a change of size, you're stuck. If you have accessor methods, then these methods can be as magical as they need to be.
It's also related to the separation of concerns. If you have public interface and the data is not public, you can change the way the data is represented any time, changing only the class that holds the data. If the data is not hidden and you change it, you have to change all of the code that uses the data.
I seldom use inheritance, but when I do, I never use protected attributes because I think it breaks the encapsulation of the inherited classes.
Do you use protected attributes ? what do you use them for ?
In this interview on Design by Bill Venners, Joshua Bloch, the author of Effective Java says:
Trusting Subclasses
Bill Venners: Should I trust subclasses more intimately than
non-subclasses? For example, do I make
it easier for a subclass
implementation to break me than I
would for a non-subclass? In
particular, how do you feel about
protected data?
Josh Bloch: To write something that is both subclassable and robust
against a malicious subclass is
actually a pretty tough thing to do,
assuming you give the subclass access
to your internal data structures. If
the subclass does not have access to
anything that an ordinary user
doesn't, then it's harder for the
subclass to do damage. But unless you
make all your methods final, the
subclass can still break your
contracts by just doing the wrong
things in response to method
invocation. That's precisely why the
security critical classes like String
are final. Otherwise someone could
write a subclass that makes Strings
appear mutable, which would be
sufficient to break security. So you
must trust your subclasses. If you
don't trust them, then you can't allow
them, because subclasses can so easily
cause a class to violate its
contracts.
As far as protected data in general,
it's a necessary evil. It should be
kept to a minimum. Most protected data
and protected methods amount to
committing to an implementation
detail. A protected field is an
implementation detail that you are
making visible to subclasses. Even a
protected method is a piece of
internal structure that you are making
visible to subclasses.
The reason you make it visible is that
it's often necessary in order to allow
subclasses to do their job, or to do
it efficiently. But once you've done
it, you're committed to it. It is now
something that you are not allowed to
change, even if you later find a more
efficient implementation that no
longer involves the use of a
particular field or method.
So all other things being equal, you
shouldn't have any protected members
at all. But that said, if you have too
few, then your class may not be usable
as a super class, or at least not as
an efficient super class. Often you
find out after the fact. My philosophy
is to have as few protected members as
possible when you first write the
class. Then try to subclass it. You
may find out that without a particular
protected method, all subclasses will
have to do some bad thing.
As an example, if you look at
AbstractList, you'll find that there
is a protected method to delete a
range of the list in one shot
(removeRange). Why is that in there?
Because the normal idiom to remove a
range, based on the public API, is to
call subList to get a sub-List,
and then call clear on that
sub-List. Without this particular
protected method, however, the only
thing that clear could do is
repeatedly remove individual elements.
Think about it. If you have an array
representation, what will it do? It
will repeatedly collapse the array,
doing order N work N times. So it will
take a quadratic amount of work,
instead of the linear amount of work
that it should. By providing this
protected method, we allow any
implementation that can efficiently
delete an entire range to do so. And
any reasonable List implementation
can delete a range more efficiently
all at once.
That we would need this protected
method is something you would have to
be way smarter than me to know up
front. Basically, I implemented the
thing. Then, as we started to subclass
it, we realized that range delete was
quadratic. We couldn't afford that, so
I put in the protected method. I think
that's the best approach with
protected methods. Put in as few as
possible, and then add more as needed.
Protected methods represent
commitments to designs that you may
want to change. You can always add
protected methods, but you can't take
them out.
Bill Venners: And protected data?
Josh Bloch: The same thing, but even more. Protected data is even more
dangerous in terms of messing up your
data invariants. If you give someone
else access to some internal data,
they have free reign over it.
Short version: it breaks encapsulation but it's a necessary evil that should be kept to a minimum.
C#:
I use protected for abstract or virtual methods that I want base classes to override. I also make a method protected if it may be called by base classes, but I don't want it called outside the class hierarchy.
You may need them for static (or 'global') attribute you want your subclasses or classes from same package (if it is about java) to benefit from.
Those static final attributes representing some kind of 'constant value' have seldom a getter function, so a protected static final attribute might make sense in that case.
Scott Meyers says don't use protected attributes in Effective C++ (3rd ed.):
Item 22: Declare data members private.
The reason is the same you give: it breaks encapsulations. The consequence is that otherwise local changes to the layout of the class might break dependent types and result in changes in many other places.
I don't use protected attributes in Java because they are only package protected there. But in C++, I'll use them in abstract classes, allowing the inheriting class to inherit them directly.
There are never any good reasons to have protected attributes. A base class must be able to depend on state, which means restricting access to data through accessor methods. You can't give anyone access to your private data, even children.
I recently worked on a project were the "protected" member was a very good idea. The class hiearchy was something like:
[+] Base
|
+--[+] BaseMap
| |
| +--[+] Map
| |
| +--[+] HashMap
|
+--[+] // something else ?
The Base implemented a std::list but nothing else. The direct access to the list was forbidden to the user, but as the Base class was incomplete, it relied anyway on derived classes to implement the indirection to the list.
The indirection could come from at least two flavors: std::map and stdext::hash_map. Both maps will behave the same way but for the fact the hash_map needs the Key to be hashable (in VC2003, castable to size_t).
So BaseMap implemented a TMap as a templated type that was a map-like container.
Map and HashMap were two derived classes of BaseMap, one specializing BaseMap on std::map, and the other on stdext::hash_map.
So:
Base was not usable as such (no public accessors !) and only provided common features and code
BaseMap needed easy read/write to a std::list
Map and HashMap needed easy read/write access to the TMap defined in BaseMap.
For me, the only solution was to use protected for the std::list and the TMap member variables. There was no way I would put those "private" because I would anyway expose all or almost all of their features through read/write accessors anyway.
In the end, I guess that if you en up dividing your class into multiple objects, each derivation adding needed features to its mother class, and only the most derived class being really usable, then protected is the way to go. The fact the "protected member" was a class, and so, was almost impossible to "break", helped.
But otherwise, protected should be avoided as much as possible (i.e.: Use private by default, and public when you must expose the method).
The protected keyword is a conceptual error and language design botch, and several modern languages, such as Nim and Ceylon (see http://ceylon-lang.org/documentation/faq/language-design/#no_protected_modifier), that have been carefully designed rather than just copying common mistakes, don't have such a keyword.
It's not protected members that breaks encapsulation, it's exposing members that shouldn't be exposed that breaks encapsulation ... it doesn't matter whether they are protected or public. The problem with protected is that it is wrongheaded and misleading ... declaring members protected (rather than private) doesn't protect them, it does the opposite, exactly as public does. A protected member, being accessible outside the class, is exposed to the world and so its semantics must be maintained forever, just as is the case for public. The whole idea of "protected" is nonsense ... encapsulation is not security, and the keyword just furthers the confusion between the two. You can help a little by avoiding all uses of protected in your own classes -- if something is an internal part of the implementation, isn't part of the class's semantics, and may change in the future, then make it private or internal to your package, module, assembly, etc. If it is an unchangeable part of the class semantics, then make it public, and then you won't annoy users of your class who can see that there's a useful member in the documentation but can't use it, unless they are creating their own instances and can get at it by subclassing.
In general, no you really don't want to use protected data members. This is doubly true if your writing an API. Once someone inherits from your class you can never really do maintenance and not somehow break them in a weird and sometimes wild way.
I use them. In short, it's a good way, if you want to have some attributes shared. Granted, you could write set/get functions for them, but if there is no validation, then what's the point? It's also faster.
Consider this: you have a class which is your base class. It has quite a few attributes you wan't to use in the child objects. You could write a get/set function for each, or you can just set them.
My typical example is a file/stream handler. You want to access the handler (i.e. file descriptor), but you want to hide it from other classes. It's way easier than writing a set/get function for it.
I think protected attributes are a bad idea. I use CheckStyle to enforce that rule with my Java development teams.
In general, yes. A protected method is usually better.
In use, there is a level of simplicity given by using a protected final variable for an object that is shared by all the children of a class. I'd always advise against using it with primitives or collections since the contracts are impossible to define for those types.
Lately I've come to separate stuff you do with primitives and raw collections from stuff you do with well-formed classes. Primitives and collections should ALWAYS be private.
Also, I've started occasionally exposing public member variables when they are declaired final and are well-formed classes that are not too flexible (again, not primitives or collections).
This isn't some stupid shortcut, I thought it out pretty seriously and decided there is absolutely no difference between a public final variable exposing an object and a getter.
It depends on what you want. If you want a fast class then data should be protected and use protected and public methods.
Because I think you should assume that your users who derive from your class know your class quite well or at least they have read your manual at the function they going to override.
If your users mess with your class it is not your problem. Every malicious user can add the following lines when overriding one of your virtuals:
(C#)
static Random rnd=new Random();
//...
if (rnd.Next()%1000==0) throw new Exception("My base class sucks! HAHAHAHA! xD");
//...
You can't seal every class to prevent this.
Of course if you want a constraint on some of your fields then use accessor functions or properties or something you want and make that field private because there is no other solution...
But I personally don't like to stick to the oop principles at all costs. Especially making properties with the only purpose to make data members private.
(C#):
private _foo;
public foo
{
get {return _foo;}
set {_foo=value;}
}
This was my personal opinion.
But do what your boss require (if he wants private fields than do that.)
I use protected variables/attributes within base classes that I know I don't plan on changing into methods. That way, subclasses have full access to their inherited variables, and don't have the (artificially created) overhead of going through getters/setters to access them. An example is a class using an underlying I/O stream; there is little reason not to allow subclasses direct access to the underlying stream.
This is fine for member variables that are used in direct simple ways within the base class and all subclasses. But for a variable that has a more complicated use (e.g., accessing it causes side effects in other members within the class), a directly accessible variable is not appropriate. In this case, it can be made private and public/protected getters/setters can be provided instead. An example is an internal buffering mechanism provided by the base class, where accessing the buffers directly from a subclass would compromise the integrity of the algorithms used by the base class to manage them.
It's a design judgment decision, based on how simple the member variable is, and how it is expected to be so in future versions.
Encapsulation is great, but it can be taken too far. I've seen classes whose own private methods accessed its member variables using only getter/setter methods. This is overkill, since if a class can't trust its own private methods with its own private data, who can it trust?
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).