When to make a method static? [closed] - language-agnostic

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I'd like to know how people decide whether to define a method as static. I'm aware that a method can only be defined as static if it doesn't require access to instance fields. So let's say we have a method that does not access instance fields, do you always define such a method as static, or only if you need to call it statically (without a reference to an instance).
Perhaps another way of asking the same question is whether you use static or non-static as the default?

I use static methods whenever I can. Advantages:
When calling a static method from inside an instance method, you can be sure that there are no side-effects on the state of the current object.
From inside a static method, you can be sure you don't accidentally modify any state of the object instance.
You can use a static method from outside the class without constructing an instance. If it was possible to make the method static, it clearly doesn't need an instance, so there's no need to require one.
Static methods may be slightly more efficient because no "this" pointer needs to be passed, and no dynamic dispatch is necessary.

Kevin Bourrillion wrote an insightful answer on this topic some time ago (admittedly from a Java perspective, but I think it's applicable to other languages too).
He argues that you should basically only use static methods for pure functions.
A "pure function" is any method which does not modify any state and whose
result depends on nothing but the
parameters provided to it. So, for
example, any function that performs
I/O (directly or indirectly) is not a
pure function, but Math.sqrt(), of
course, is.
I tend to agree. (Although in my own code, traditionally, I've probably used way too many static helper methods all over the place... :-P And this surely has made code that uses those methods harder to test.)

If what the method does depend solely on its arguments, you can make it static. If the method does not instantiate any other of your user defined classes, you can make it static. The default, though, is to have it as non-static.

Use static methods when you are performing operations that do not operate on instances of the class.
A perfect example would be a sqrt method of a Math class.

It depends. In languages where non-member functions are possible I'd say that most of the time, if the method could be made static, it should be made a non-member function instead, non-friend if possible. You can tell I have a mostly C++ background.
In "pure" OO languages where non-member functions are not possible it would depend on whether the method is only "incidentally" static (i.e. it just happens not to need access to instance members), or is truly logically static - it is a method of the whole class instead of for a particular instance.

Non static by default, static when I need the functionality to be available from at least two different classes, and I don't want to waste a constructor.
ps. Archimedes rules!

(C#) By default, I use static methods in static classes and non-static methods in non-static classes.
As I elaborate a class, I find myself naturally converging on making it entirely static or entirely non-static. Practially speaking, if I start wanting to define static members within a non-static class, I often find that it will eventually make the most sense to break those out into a separate static class -- either a utility class like Math or a global application class (like .NET's ConfigurationManager).
From an object-oriented perspective, a method is doing something to/with an object. So if you're using an instantiated object, it makes the most sense to me to think of that object's methods as non-static. Technically, you technically can make a non-static class have static members if they don't require access to an instance. But ostensibly, at least, a class's methods would still be doing something to/with that class, so I would still make them non-static. All things being equal, that is.

in context of python -
staticmethod are basically a normal function, we keep in the class only because of some logical reasons. classmethod takes 'class' as a first argument, default method takes instance aka self as a first argument but staticmethod does not takes any any argument.

Related

Is Method Overloading considered polymorphism? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
Is Method Overloading considered part of polymorphism?
There are different types of polymorphism:
overloading polymorphism (also called Ad-hoc polymorphism)
overriding polymorphism
So yes it is part of polymorphism.
"Polymorphism" is just a word and doesn't have a globally agreed-upon, precise definition. You will not be enlightened by either a "yes" or a "no" answer to your question because the difference will be in the chosen definition of "polymorphism" and not in the essence of method overloading as a feature of any particular language. You can see the evidence of that in most of the other answers here, each introducing its own definition and then evaluating the language feature against it.
Strictly speaking polymorphism, from wikipedia:
is the ability of one type, A, to appear as and be used like another type, B.
So, method overloading as such is not considered part of this definition polymorphism, as the overloads are defined as part of one type.
If you are talking about inclusion polymorphism (normally thought of as overriding), that is a different matter and then, yes it is considered to be part of polymorphism.
inclusion polymorphism is a concept in type theory wherein a name may denote instances of many different classes as long as they are related by some common super class.
There are 2 types of polymorphism.
static
dynamic.
Overloading is of type static polymorphism.. overriding comes under dynamic (or run-time) polymorphism..
ref. http://en.wikipedia.org/wiki/Polymorphism_(computer_science) which describes it more.
No, overloading is not. Maybe you refer to method overriding which is indeed part of polymorphism.
To further clarify, From the wikipedia:
Polymorphism is not the same as method
overloading or method overriding.1
Polymorphism is only concerned with
the application of specific
implementations to an interface or a
more generic base class.
So I'd say method overriding AND method overloading and convenient features of some language regarding polymorphism but notthe main concern of polymorphism (in object oriented programming) which only regards to the capability of an object to act as if it was another object in its hierarchy chain.
Method overriding or overloading is not polymorphism.
The right way to put it is that Polymorphism can be implemented using method overriding or overloading and using other ways as well.
In order to implement Polymorphism using method overriding, you can override the behaviour of a method in a sub-class.
In order to implement Polymorphism using method overloading, you need to write many methods with the same name and the same number of parameters but with different data types and implement different behavious in these methods. Now that is also polymorphism.
Other ways to implement polymorphism is operator overloading and implementing interfaces.
Wikipedia pedantics aside, one way to think about polymorphism is: the ability for a single line of code / single method call to do different things at runtime depending on the type of the object instance used to make the call.
Method overloading does not change behaviors at runtime. Overloading gives you more choices for argument lists on the same method name when you're writing and compiling the code, but when it's compiled the choice is fixed in code forever.
Not to be confused with method overriding, which is part of polymorphism.
It's a necessary evil that is and should only be used as a complement. In the end overloads should only convert and eventually forward to the main method. OverloDing is necessary because most vms for staticalky dispatched environments don't know how to convert one type to another so the parameter fits the target and this is where one uses overloads to help out.
StringBuilder
Append(String) // main
Append(Boolean) // converts and calls append(String)

Is a Class special when it has no members?

I just realize some of my classes have no members. It has several public functions and maybe private functions and everything is passes through params. I realize functional programmers do this all the time but is this class considered special if it access nothing outside of the class and only uses its params for reading (except for out params and return values)?
I know this class can be static but static classes can modify outside variables. I want to know if this is a technique or maybe if a language may give additional benefits for writing it this way and etc.
-edit- This is looking like a wiki so lets make it one.
It is just called "stateless". Nothing really special about it.
There is nothing wrong with a class that has no members; controllers do this very frequently.
Yes, you could go static, but by not being static you allow for inheritance from your memberless class, which could add members along the way, if you so desired.
If there are no members, then there is no need for a class other than having a namespace. If you were programming in Python, then you would just put those methods into a module and don't bother with a class. If you are working in Java, then a a class is a must. If you are working in C++, it's up to you - but maybe you should consider using just a namespace, instead of a class, to make it less confusing.
Yes, this makes the class completely thread safe and thus no locking is required. To me, that is a fantastic attribute.
Sane programming languages allow you to define functions outside of classes when the functions do not require any persistent data - if you can define it in an appropriate namespace, all the better. If your language does not allow that, at least define them in a static class so it's clear that no state is accessed or mutated. Overall, though, this reminds me of an excellent article on the illogical abuse of classes in the name of "pure OOP".
I'd make the class static. I don't see what advantage it would give to keep it non-static. But then again - I'm a .NET developer, not Java. The languages are close, but there are many subtle differences I'm not aware of.
Remember that all methods of your class (even stateless) have one special variable -- pointer/reference to object - this (self, whatever) for which they are applied to.
Thus it is perfect sense in such stateless class if its methods could be overridden: in this case you have to have class to provide dispatching by this.
(Of course it's just emulating of first-class functions, so if your language already has ones it's no sense in this technique.)
At the moment I can't imagine why would you need stateless class without any virtual method.
Unless you want to have nice auto-complete in your IDE by typing objectName and dot :)
its simple class there is no specialty in it.
But i dont understand what is the use of having public or private methods when there in no member in it. because member methods are those which acts on particular instance's state.
Yes you can have static methods in it.

Subclasses causing unexpected behavior in superclasses — OO design question

Although I'm coding in ObjC, This question is intentionally language-agnostic - it should apply to most OO languages
Let's say I have an "Collection" class, and I want to create a "FilteredCollection" that inherits from "Collection". Filters will be set up at object-creation time, and from them on, the class will behave like a "Collection" with the filters applied to its contents.
I do things the obvious way and subclass Collection. I override all the accessors, and think I've done a pretty neat job - my FilteredCollection looks like it should behave just like a Collection, but with objects that are 'in' it that correspond to my filters being filtered out to users. I think I can happily create FilteredCollections and pass them around my program as Collections.
But I come to testing and - oh no - it's not working. Delving into the debugger, I find that it's because the Collection implementation of some methods is calling the overridden FilteredCollection methods (say, for example, there's a "count" method that Collection relies upon when iterating its objects, but now it's getting the filtered count, because I overrode the count method to give the correct external behaviour).
What's wrong here? Why does it feel like some important principles are being violated despite the fact that it also feels like OO 'should' work this way? What's a general solution to this issue? Is there one?
I know, by the way, that a good 'solution' to this problem in particular would be to filter the objects before I put them into the collection, and not have to change Collection at all, but I'm asking a more general question than that - this is just an example. The more general issue is methods in an opaque superclass that rely on the behaviour of other methods that could be changed by subclasses, and what to do in the case that you want to subclass an object to change behaviour like this.
The Collection that you inherit from has a certain contract. Users of the class (and that includes the class itself, because it can call its own methods) assume that subclasses obey the contract. If you're lucky, the contract is specified clearly and unambiguously in its documentation...
For example, the contract could say: "if I add an element x, then iterate over the collection, I should get x back". It seems that your FilteredCollection implementation breaks that contract.
There is another problem here: Collection should be an interface, not a concrete implementation. An implementation (e.g. TreeSet) should implement that interface, and of course also obey its contract.
In this case, I think the correct design would be not to inherit from Collection, but rather create FilteredCollection as a "wrapper" around it. Probably FilteredCollection should not implement the Collection interface, because it does not obey the usual contract for collections.
Rather than sublcassing Collection to implement FilteredCollection, try implementing FilteredCollection as a separate class that implements iCollection and delegates to an existing collection. This is similar to the Decorator pattern from the Gang of Four.
Partial example:
class FilteredCollection implements ICollection
{
private ICollection baseCollection;
public FilteredCollection(ICollection baseCollection)
{
this.baseCollection = baseCollection;
}
public GetItems()
{
return Filter(baseCollection.GetItems());
}
private Filter(...)
{
//do filter here
}
}
Implementing FilteredCollection as a decorator for ICollection has the added benefit that you can filter anything that implements ICollection, not just the one class you subclassed.
For added goodness, you can use the Command pattern to inject a specific implementation of Filter() into the FilteredCollection at runtime, eliminating the need to write a different FilteredCollection implementation for every filter you want to apply.
(Note whilst I'll use your example I'll try to concentrate on the concept rather then tell you what's wrong with your specific example).
Black Box Inheritance?
What you're crashing into is the myth of "Black box inheritance". Its often not actually possible to separate completely implementations that allow inheritance from implementations that use that inheritance. I know this flys in the face of how inheritance is often taught but there it is.
To take your example, its quite reasonable for you to want the consumers of the collection contract to see a Count which matches the number items they can get out of your collection. Its also quite reasonable for code in the inherited base class to access its Count property and get what it expects. Something has to give.
Who is Responsible?
Answer: The base class. To achieve both the goals above the base class needs to handle things differently. Why is this the reponsibility of the base class? Because it allows itself to be inherited from and allowed the member implementation to be overriden. Now it may be in some languages that facilitate an OO design that you aren't given a choice. However that just makes this problem harder to deal with but it still needs be dealt with.
In the example, the base collection class should have its own internal means of determining its actual count in the knowledge that a sub-class may override the existing implementation of Count. Its own implementation of the public and overridable Count property should not impact on the internal operation of the base class but just be a means to acheive the external contract it is implementing.
Of course this means the implementation of the base class isn't as crisp and clean as we would like. That's what I mean by the black box inheritance being a myth, there is some implementation cost just to allow inheritance.
The Bottom Line...
is an inheritable class needs to be coded defensively so that it doesn't rely on assumed operation of overridable members. OR it needs to be very clear in some form of documentation exactly what behaviour is expected from overriden implementations of members (this is common in classes that define abstract members).
Your FilteredCollection feels wrong. Usually, when you have a collection and you add a new element into it, you expect that it's count increases by one, and the new element is added to the container.
Your FilteredCollection does not work like this - if you add an item that is filtered, the count of the container might not change. I think this is where your design goes wrong.
If that behaviour is intended, then the contract for count makes it unsuitable for the purpose your member functions are trying to use it for.
I think that the real issue is a misunderstanding of how object-oriented languages are supposed to work. I'm guessing that you have code that looks something like this:
Collection myCollection = myFilteredCollection;
And expect to invoke the methods implemented by the Collection class. Correct?
In a C++ program, this might work, provided that the methods on Collection are not defined as virtual methods. However, this is an artifact of the design goals of C++.
In just about every other object-oriented language, all methods are dispatched dynamically: they use the type of the actual object, not the type of the variable.
If that's not what you're wondering, then read up on the Liskov Substitution Principle, and ask yourself whether you're breaking it. Lots of class hierarchies do.
What you described is a quirk of polymorphism. Since you can address an instance of a subclass as an instance of the parent class, you may not know what kind of implementation lies underneath the covers.
I think your solution is pretty simple:
You stated that you don't modify the collection, you only apply a filter to it when people fetch from it. Therefore you should not override the count method. All of those elements are in the collection therefore don't lie to the caller.
You want the base .count method to behave normally, but you still want the count so you should implement a getFilteredCount method which returns the amount of elements post filtering.
Subclassing is all about the 'Kind of' relationship. What you're doing is not out of the norm but not the most standard use case either. You're applying a filter to a collection, so you can claim that a 'FilteredCollection' is a 'kind of' collection, but in reality you're not actually modifying the collection; you're just wrapping it with a layer that simplifies filtering. In any case, this should work. The only downside is that you have to remember to call 'getFilteredCount' instead of .getCount
The example falls into "Doctor, it hurts when I do this" category. Yes, subclasses can break superclasses in various ways. No, there is no simple waterproof solution to prevent that.
You can seal your superclass (make everything final) if your language supports this but then you lose flexibility. This is the bad kind of defensive programming (the good relies on robust code, the bad relies on strong restrictions).
The best you can do is to act at human level - make sure that the human that writes the subclass understands the superclass. Tutoring/code review, good documentation, unit tests (in roughly this order of importance) can help achieve this. And of course it doesn't hurt to code the base class defensively.
You could argue that the superclass is not well-designed for subclassing, at least not in the way you want to. When the superclass calls "Count()" or "Next()" or whatever, it doesn't have to let that call be overridden. In c++, it can't be overridden unless it's declared "virtual", but that doesn't apply in all languages - for example, Obj-C is inherently virtual if I remember correctly.
It's even worse - this problem can happen to you even if you don't override methods in the superclass - see Subtyping vs Subclassing. See in particular the OOP problems reference in that article.
It behaves this way because this is how object-oriented programming is supposed to work!
The whole point of OOP is supposed to be that a sub-class can redefine some of its superclasses methods, and then operations done at the superclass level will get the subclass implementation.
Let's make your example a little more concrete. We create a "Collection animal" that contains dog, cat, lion, and basilisk. Then we create a FilteredCollection domesticAnimal that filters out the lion and basilisk. So now if we iterate over domesticAnimal we expect to see only dog and cat. If we ask for a count of the number of members, would we not expect the result to be "2"? It would surely be curious behavior if we asked the object how many members it had and it said "4", and then when we asked it to list them it only listed 2.
Making the overrides work at the superclass level is an important feature of OOP. It allows us to define a function that takes, in your example, a Collection object as a parameter and operates on it, without knowing or caring whether underneath it is really a "pure" Collection or a FilteredCollection. Everything should work either way. If it's a pure Collection it gets the pure Collection functions; if it's a FilteredCollection it gets the FilteredCollection functions.
If the count is also used internally for other purposes -- like deciding where new elements should go, so that you add what is really a fifth element and it mysteriously overwrites #3 -- then you have a problem in the design of the classes. OOP gives you great power over how classes operate, but with great power comes great responsibility. :-) If a function is used for two different purposes, and you override the implementation to satisfy your requirements for purpose #1, it's up to you to make sure that that doesn't break purpose #2.
My first reaction to your post was the mention of overriding "all the accessors." This is something I've seen a lot of: extending a base class then overriding most of the base class methods. This defeats the purpose of inheritance in my opinion. If you need to override most base class functions then it's time to reconsider why you're extending the class. As said before, an interface may be a better solution, since it loosely couples disparate objects. The sub-class should EXTEND the functionality of the base class, not completely rewrite it.
I couldn't help but wonder if you are overriding the base class members then it would seem quite logical that unexpected behavior would occur.
When I first grok'd how inheritance worked I used it a lot. I had these big trees with everything connected one way or another.
What a pain.
For what you want, you should be referencing your object, not extending it.
Also, I'd personally hide any trace of passing a collection from my public API (and, in general, my private API as well). Collections are impossible to make safe. Wrapping a collection (Come on, what's it used for??? You can guess just from the signature, right?) inside a WordCount class or a UsersWithAges class or a AnimalsAndFootCount class can make a lot more sense.
Also having methods like wordCount.getMostUsedWord(), usersWithAges.getUsersOverEighteen() and animalsAndFootCount.getBipeds() method moves repetitive utility functionality scattered throughout your code into your new-fangled business collection where it belongs.

When should a method be static?

In addition, are there any performance advantages to static methods over instance methods?
I came across the following recently: http://www.cafeaulait.org/course/week4/22.html :
When should a method be static?
Neither reads from nor writes to instance fields
Independent of the state of the object
Mathematical methods that accept arguments, apply an algorithm to those
arguments, and return a value
Factory methods that serve in lieu of constructors
I would be very interested in the feedback of the Stack Overflow community on this.
Make methods static when they are not part of the instance. Don't sweat the micro-optimisations.
You might find you have lots of private methods that could be static but you always call from instance methods (or each other). In that case it doesn't really matter that much. However, if you want to actually be able to test your code, and perhaps use it from elsewhere, you might want to consider making those static methods in a different, non-instantiable class.
Whether or not a method is static is more of a design consideration than one of efficiency. A static method belongs to a class, where a non-static method belongs to an object. If you had a Math class, you might have a few static methods to deal with addition and subtraction because these are concepts associated with Math. However, if you had a Car class, you might have a few non-static methods to change gears and steer, because those are associated with a specific car, and not the concept of cars in general.
Another problem with static methods is that it is quite painful to write unit tests for them - in Java, at least. You cannot mock a static method in any way. There is a post on google testing blog about this issue.
My rule of thumb is to write static methods only when they have no external dependencies (like database access, read files, emails and so on) to keep them as simple as possible.
Just remember that whenever you are writing a static method, you are writing an inflexible method that cannot have it's behavior modified very easily.
You are writing procedural code, so if it makes sense to be procedural, then do it. If not, it should probably be an instance method.
This idea is taken from an article by Steve Yegge, which I think is an interesting and useful read.
#jagmal I think you've got some wires crossed somewhere - all the examples you list are clearly not static methods.
Static methods should deal entirely with abstract properties and concepts of a class - they should in no way relate to instance specific attributes (and most compilers will yell if they do).
For the car example, speed, kms driven are clearly attribute related. Gear shifting and speed calculation, when considered at the car level, are attribute dependent - but consider a carModel class that inherits from car: at this point theyy could become static methods, as the required attributes (such as wheel diameter) could be defined as constants at that level.
Performance-wise, a C++ static method can be slightly faster than a non-virtual instance method, as there's no need for a 'this' pointer to get passed to the method. In turn, both will be faster than virtual methods as there's no VMT lookup needed.
But, it's likely to be right down in the noise - particularly for languages which allow unnecessary parameter passing to be optimized out.
Here is a related discussion as to why String.Format is static that will highlight some reasons.
Another thing to consider when making methods static is that anyone able to see the class is able to call a static method. Whereas when the mehtod is an instance method, only those who have access to an instance are able to call that method.

Private vs. Public members in practice (how important is encapsulation?) [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
One of the biggest advantages of object-oriented programming is encapsulation, and one of the "truths" we've (or, at least, I've) been taught is that members should always be made private and made available via accessor and mutator methods, thus ensuring the ability to verify and validate the changes.
I'm curious, though, how important this really is in practice. In particular, if you've got a more complicated member (such as a collection), it can be very tempting to just make it public rather than make a bunch of methods to get the collection's keys, add/remove items from the collection, etc.
Do you follow the rule in general? Does your answer change depending on whether it's code written for yourself vs. to be used by others? Are there more subtle reasons I'm missing for this obfuscation?
It depends. This is one of those issues that must be decided pragmatically.
Suppose I had a class for representing a point. I could have getters and setters for the X and Y coordinates, or I could just make them both public and allow free read/write access to the data. In my opinion, this is OK because the class is acting like a glorified struct - a data collection with maybe some useful functions attached.
However, there are plenty of circumstances where you do not want to provide full access to your internal data and rely on the methods provided by the class to interact with the object. An example would be an HTTP request and response. In this case it's a bad idea to allow anybody to send anything over the wire - it must be processed and formatted by the class methods. In this case, the class is conceived of as an actual object and not a simple data store.
It really comes down to whether or not verbs (methods) drive the structure or if the data does.
As someone having to maintain several-year-old code worked on by many people in the past, it's very clear to me that if a member attribute is made public, it is eventually abused. I've even heard people disagreeing with the idea of accessors and mutators, as that's still not really living up to the purpose of encapsulation, which is "hiding the inner workings of a class". It's obviously a controversial topic, but my opinion would be "make every member variable private, think primarily about what the class has got to do (methods) rather than how you're going to let people change internal variables".
Yes, encapsulation matters. Exposing the underlying implementation does (at least) two things wrong:
Mixes up responsibilities. Callers shouldn't need or want to understand the underlying implementation. They should just want the class to do its job. By exposing the underlying implementation, you're class isn't doing its job. Instead, it's just pushing the responsibility onto the caller.
Ties you to the underlying implementation. Once you expose the underlying implementation, you're tied to it. If you tell callers, e.g., there's a collection underneath, you cannot easily swap the collection for a new implementation.
These (and other) problems apply regardless of whether you give direct access to the underlying implementation or just duplicate all the underlying methods. You should be exposing the necessary implementation, and nothing more. Keeping the implementation private makes the overall system more maintainable.
I prefer to keep members private as long as possible and only access em via getters, even from within the very same class. I also try to avoid setters as a first draft to promote value style objects as long as it is possible. Working with dependency injection a lot you often have setters but no getters, as clients should be able to configure the object but (others) not get to know what's acutally configured as this is an implementation detail.
Regards,
Ollie
I tend to follow the rule pretty strictly, even when it's just my own code. I really like Properties in C# for that reason. It makes it really easy to control what values it's given, but you can still use them as variables. Or make the set private and the get public, etc.
Basically, information hiding is about code clarity. It's designed to make it easier for someone else to extend your code, and prevent them from accidentally creating bugs when they work with the internal data of your classes. It's based on the principle that nobody ever reads comments, especially ones with instructions in them.
Example: I'm writing code that updates a variable, and I need to make absolutely sure that the Gui changes to reflect the change, the easiest way is to add an accessor method (aka a "Setter"), which is called instead of updating data is updated.
If I make that data public, and something changes the variable without going through the Setter method (and this happens every swear-word time), then someone will need to spend an hour debugging to find out why the updates aren't being displayed. The same applies, to a lesser extent, to "Getting" data. I could put a comment in the header file, but odds are that no-one will read it till something goes terribly, terribly wrong. Enforcing it with private means that the mistake can't be made, because it'll show up as an easily located compile-time bug, rather than a run-time bug.
From experience, the only times you'd want to make a member variable public, and leave out Getter and Setter methods, is if you want to make it absolutely clear that changing it will have no side effects; especially if the data structure is simple, like a class that simply holds two variables as a pair.
This should be a fairly rare occurence, as normally you'd want side effects, and if the data structure you're creating is so simple that you don't (e.g a pairing), there will already be a more efficiently written one available in a Standard Library.
With that said, for most small programs that are one-use no-extension, like the ones you get at university, it's more "good practice" than anything, because you'll remember over the course of writing them, and then you'll hand them in and never touch the code again. Also, if you're writing a data structure as a way of finding out about how they store data rather than as release code, then there's a good argument that Getters and Setters will not help, and will get in the way of the learning experience.
It's only when you get to the workplace or a large project, where the probability is that your code will be called to by objects and structures written by different people, that it becomes vital to make these "reminders" strong. Whether or not it's a single man project is surprisingly irrelevant, for the simple reason that "you six weeks from now" is as different person as a co-worker. And "me six weeks ago" often turns out to be lazy.
A final point is that some people are pretty zealous about information hiding, and will get annoyed if your data is unnecessarily public. It's best to humour them.
C# Properties 'simulate' public fields. Looks pretty cool and the syntax really speeds up creating those get/set methods
Keep in mind the semantics of invoking methods on an object. A method invocation is a very high level abstraction that can be implemented my the compiler or the run time system in a variety of different ways.
If the object who's method you are invoking exists in the same process/ memory map then a method could well be optimized by a compiler or VM to directly access the data member. On the other hand if the object lives on another node in a distributed system then there is no way that you can directly access it's internal data members, but you can still invoke its methods my sending it a message.
By coding to interfaces you can write code that doesn't care where the target object exists or how it's methods are invoked or even if it's written in the same language.
In your example of an object that implements all the methods of a collection, then surely that object actually is a collection. so maybe this would be a case where inheritance would be better than encapsulation.
It's all about controlling what people can do with what you give them. The more controlling you are the more assumptions you can make.
Also, theorectically you can change the underlying implementation or something, but since for the most part it's:
private Foo foo;
public Foo getFoo() {}
public void setFoo(Foo foo) {}
It's a little hard to justify.
Encapsulation is important when at least one of these holds:
Anyone but you is going to use your class (or they'll break your invariants because they don't read the documentation).
Anyone who doesn't read the documentation is going to use your class (or they'll break your carefully documented invariants). Note that this category includes you-two-years-from-now.
At some point in the future someone is going to inherit from your class (because maybe an extra action needs to be taken when the value of a field changes, so there has to be a setter).
If it is just for me, and used in few places, and I'm not going to inherit from it, and changing fields will not invalidate any invariants that the class assumes, only then I will occasionally make a field public.
My tendency is to try to make everything private if possible. This keeps object boundaries as clearly defined as possible and keeps the objects as decoupled as possible. I like this because when I have to rewrite an object that I botched the first (second, fifth?) time, it keeps the damage contained to a smaller number of objects.
If you couple the objects tightly enough, it may be more straightforward just to combine them into one object. If you relax the coupling constraints enough you're back to structured programming.
It may be that if you find that a bunch of your objects are just accessor functions, you should rethink your object divisions. If you're not doing any actions on that data it may belong as a part of another object.
Of course, if you're writing a something like a library you want as clear and sharp of an interface as possible so others can program against it.
Fit the tool to the job... recently I saw some code like this in my current codebase:
private static class SomeSmallDataStructure {
public int someField;
public String someOtherField;
}
And then this class was used internally for easily passing around multiple data values. It doesn't always make sense, but if you have just DATA, with no methods, and you aren't exposing it to clients, I find it a quite useful pattern.
The most recent use I had of this was a JSP page where I had a table of data being displayed, defined at the top declaratively. So, initially it was in multiple arrays, one array per data field... this ended in the code being rather difficult to wade through with fields not being next to eachother in definition that would be displayed together... so I created a simple class like above which would pull it together... the result was REALLY readable code, a lot more so than before.
Moral... sometimes you should consider "accepted bad" alternatives if they may make the code simpler and easier to read, as long as you think it through and consider the consequences... don't blindly accept EVERYTHING you hear.
That said... public getters and setters is pretty much equivalent to public fields... at least essentially (there is a tad more flexibility, but it is still a bad pattern to apply to EVERY field you have).
Even the java standard libraries has some cases of public fields.
When I make objects meaningful they are easier to use and easier to maintain.
For example: Person.Hand.Grab(howquick, howmuch);
The trick is not to think of members as simple values but objects in themselves.
I would argue that this question does mix-up the concept of encapsulation with 'information hiding'
(this is not a critic, since it does seem to match a common interpretation of the notion of 'encapsulation')
However for me, 'encapsulation' is either:
the process of regrouping several items into a container
the container itself regrouping the items
Suppose you are designing a tax payer system. For each tax payer, you could encapsulate the notion of child into
a list of children representing the children
a map of to takes into account children from different parents
an object Children (not Child) which would provide the needed information (like total number of children)
Here you have three different kinds of encapsulations, 2 represented by low-level container (list or map), one represented by an object.
By making those decisions, you do not
make that encapsulation public or protected or private: that choice of 'information hiding' is still to be made
make a complete abstraction (you need to refine the attributes of object Children and you may decide to create an object Child, which would keep only the relevant informations from the point of view of a tax payer system)
Abstraction is the process of choosing which attributes of the object are relevant to your system, and which must be completely ignored.
So my point is:
That question may been titled:
Private vs. Public members in practice (how important is information hiding?)
Just my 2 cents, though. I perfectly respect that one may consider encapsulation as a process including 'information hiding' decision.
However, I always try to differentiate 'abstraction' - 'encapsulation' - 'information hiding or visibility'.
#VonC
You might find the International Organisation for Standardization's, "Reference Model of Open Distributed Processing," an interesting read. It defines: "Encapsulation: the property that the information contained in an object is accessible only through interactions at the interfaces supported by the object."
I tried to make a case for information hiding's being a critical part of this definition here:
http://www.edmundkirwan.com/encap/s2.html
Regards,
Ed.
I find lots of getters and setters to be a code smell that the structure of the program is not designed well. You should look at the code that uses those getters and setters, and look for functionality that really should be part of the class. In most cases, the fields of a class should be private implementation details and only the methods of that class may manipulate them.
Having both getters and setters is equal to the field being public (when the getters and setters are trivial/generated automatically). Sometimes it might be better to just declare the fields public, so that the code will be more simple, unless you need polymorphism or a framework requires get/set methods (and you can't change the framework).
But there are also cases where having getters and setters is a good pattern. One example:
When I create the GUI of an application, I try to keep the behaviour of the GUI in one class (FooModel) so that it can be unit tested easily, and have the visualization of the GUI in another class (FooView) which can be tested only manually. The view and model are joined with simple glue code; when the user changes the value of field x, the view calls setX(String) on the model, which in turn may raise an event that some other part of the model has changed, and the view will get the updated values from the model with getters.
In one project, there is a GUI model which has 15 getters and setters, of which only 3 get methods are trivial (such that the IDE could generate them). All the others contain some functionality or non-trivial expressions, such as the following:
public boolean isEmployeeStatusEnabled() {
return pinCodeValidation.equals(PinCodeValidation.VALID);
}
public EmployeeStatus getEmployeeStatus() {
Employee employee;
if (isEmployeeStatusEnabled()
&& (employee = getSelectedEmployee()) != null) {
return employee.getStatus();
}
return null;
}
public void setEmployeeStatus(EmployeeStatus status) {
getSelectedEmployee().changeStatusTo(status, getPinCode());
fireComponentStateChanged();
}
In practice I always follow only one rule, the "no size fits all" rule.
Encapsulation and its importance is a product of your project. What object will be accessing your interface, how will they be using it, will it matter if they have unneeded access rights to members? those questions and the likes of them you need to ask yourself when working on each project implementation.
I base my decision on the Code's depth within a module.
If I'm writting code that is internal to a module, and does not interface with the outside world I don't encapsulate things with private as much because it affects my programmer performance (how fast I can write and rewrite my code).
But for the objects that server as the module's interface with user code, then I adhere to strict privacy patterns.
Certainly it makes a difference whether your writing internal code or code to be used by someone else (or even by yourself, but as a contained unit.) Any code that is going to be used externally should have a well defined/documented interface that you'll want to change as little as possible.
For internal code, depending on the difficulty, you may find it's less work to do things the simple way now, and pay a little penalty later. Of course Murphy's law will ensure that the short term gain will be erased many times over in having to make wide-ranging changes later on where you needed to change a class' internals that you failed to encapsulate.
Specifically to your example of using a collection that you would return, it seems possible that the implementation of such a collection might change (unlike simpler member variables) making the utility of encapsulation higher.
That being said, I kinda like Python's way of dealing with it. Member variables are public by default. If you want to hide them or add validation there are techniques provided, but those are considered the special cases.
I follow the rules on this almost all the time. There are four scenarios for me - basically, the rule itself and several exceptions (all Java-influenced):
Usable by anything outside of the current class, accessed via getters/setters
Internal-to-class usage typically preceded by 'this' to make it clear that it's not a method parameter
Something meant to stay extremely small, like a transport object - basically a straight shot of attributes; all public
Needed to be non-private for extension of some sort
There's a practical concern here that isn't being addressed by most of the existing answers. Encapsulation and the exposure of clean, safe interfaces to outside code is always great, but it's much more important when the code you're writing is intended to be consumed by a spatially- and/or temporally-large "user" base. What I mean is that if you plan on somebody (even you) maintaining the code well into the future, or if you're writing a module that will interface with code from more than a handful of other developers, you need to think much more carefully than if you're writing code that's either one-off or wholly written by you.
Honestly, I know what wretched software engineering practice this is, but I'll oftentimes make everything public at first, which makes things marginally faster to remember and type, then add encapsulation as it makes sense. Refactoring tools in most popular IDEs these days makes which approach you use (adding encapsulation vs. taking it away) much less relevant than it used to be.