This is a great question. I thought that myself, so I tried to make a system where I couldn't access x and y. It turns out it's completely reasonable to do so. If you want to move a point, you add a translate method. If you want to compare points you can. You can add and subtract points. If you want to align a group of points on the X access, you can write a method on point to do it. There were very few times when I wanted to actually access x and y rather than act on it.
I do agree, though, nobody actually writes code like that. Does that mean that I think nobody actually does OO? I hadn't actually thought it through that far :-) I think this is why the concept is so vague (your excellent example being a great indicator of that). C++ is often referred to as "C with Objects" and I sometimes think we've gone so far as to say anything with a function that operates on a structure is "Object Oriented". If so, I think we've lost our path a little bit.
You can keep adding mathematical transformations to the Point object all day long (though at some point you'll realize the mathematical operations don't belong there, and the concept of "point" isn't abstract enough - the study of right abstractions here is called "algebra"). But there comes a moment when you want to draw that point on the screen, and suddenly there's a good chance you'll have to access individual components, because the API of your drawing device doesn't understand your particular Point class.
Arguably this is still within purview of "Point" abstraction, but:
> If you want to align a group of points on the X access, you can write a method on point to do it.
This calls for a static method really, otherwise the abstraction becomes subtly wrong. And with static methods you quickly realize that you're using the containing class as just a namespace.
CLOS actually resolves this nicely by having methods being their own things separate from classes. As a related side effect, the typical C++/Java case of "object methods" isn't a special thing in CLOS, it's just a method that happens to be polymorphic only on its first argument. The abstraction around methods seems cleaner, and the class in CLOS is just responsible for encapsulation and inheritance, not for namespacing methods.
It sounds like all you're really doing is taking any function that does want access to X and Y, and shoving it into the Point object where it has that access. Or to put it another way, you're defining any function that wants access as "part of the concept of point". You can indeed accommodate any code with this transform, but is it the right thing to do? Do you gain anything by bloating up 'point' with transformations and comparisons and alignment operators and so on?
Of course you gain something. By encapsulating all methods that operate on X and Y in a single place, Point (where X and Y are defined), it is now _much_ easier to change X and Y. It's all right there in one file.
Point {x, y} may not be the best example, but you can certainly see how this can be beneficial should X or Y become something even slightly more complex. And this is the purpose of encapsulation - to make a system easier to understand and therefore easier to change.
I do agree, though, nobody actually writes code like that. Does that mean that I think nobody actually does OO? I hadn't actually thought it through that far :-) I think this is why the concept is so vague (your excellent example being a great indicator of that). C++ is often referred to as "C with Objects" and I sometimes think we've gone so far as to say anything with a function that operates on a structure is "Object Oriented". If so, I think we've lost our path a little bit.