When Object oriented design first came on the scene there was a great deal of excitement. One of the early mantra's was that with the OO programming paradigm you can create complex data types which not only contains data but also the behaviour associated with that data.
The most obvious example of this is in the case of the Vector data structure. The standard vector consists of three scalars, x, y and z, and as my ever persistent matric science teacher was at pains to point out, "has magnitude and direction".
With OO you can create a data structure which contains the 3 scalars and a collection of methods in the same context as the scalars to allow the vector interact with other vectors. Addition, multiplication and dot product etc.
However, I'm not so sure if this is the key to the success of OO, nor that this paradigm should be ubiquitously applied.
It's probably fair to say that the majority of data types that are built in modern programming do not have such a tight coupling between their behaviour and their data and therefore this encapsulation should, in most circumstances, not take place.
In the case of the vector, it is in fact defined by its behaviour; the vector is an entity which has this set of data and behaves in this way. The same cannot be said about a Person object for instance.
Let's change tack for a second and look at what would happen if we do enapsulate the behaviour of an object with its data.
Consider a person object, it contains the name, surname, birthday etc of a Person. If we place behaviour for the person object into the person object it becomes prohibitively difficult to reuse that behaviour, for a different person object for instance. If we wish to use that behaviour we have go via the Person object itself. It also means that we cannot change the behaviour without affecting the data.
It is therefore better to create a data object which only contains the data associated with the Person and then another object which contains the behaviour associated with the person.
So then you might be asking, doesn't that make the data object little more than a struct, a concept which was part of the procedural programming paradigm? You would be right, but then that begs the question, why is the OO paradigm better?
The key to the OO paradigm is not that data can be associated with it's behaviour but that behaviour can be treated as a variable. The strength of a variable is that it is exactly that, it can change, it can be assigned and it can therefore be moved around. Now with the OO model we can pass behaviour around like a variable is passed around. With the introduction of objects, which have behaviour (methods), we can now treat behaviour like we would treat a string for example. We can pass it in as a parameter for a method, we can change the behaviour as easily as changing a variables value.
How is this achieved? It is achieved by something that was formally introduced in Java, the "interface". C++ fully supported interfaces in their "abstract classes with no implemented methods" guise, java however, created a new class type. Interfaces are exactly that, abstract classes with no implemented methods. In java, though it does not have multiple inheritance, there is no limit on the number of interfaces a class can implement.
If you write an object which contains functionality associated with a Person object then you would create an interface with which this behaviour would know how to talk. Your person object would then implement that interface, and by so doing, would be able to be acted upon by the functionality you have created.
Whether to separate behaviour from data is a decision that should always be looked at. Conjoining behaviour with data should only be done when the behaviour and data are tightly coupled. Making behaviour mobile is arguably the key advantage of the OO approach, and one that should be leveraged as much as possible.