I was just reading a modern “what is clean code” book and once again found the same example being used to motivate the discussion of “data abstraction” as in many previous “clean code”/”O-O design”/”coding standard” books: The classic Point class.
Yes, the Point is currently represented in Cartesian coordinates but someday you might want to switch it to polar coordinates, and thus you should use data abstraction to expose getters and setters instead of fields.
The problem is that there is no circumstance whatsoever under which you would ever want to change a Point representation from Cartesian to Polar, or vice versa, where you would want that change to happen in isolation without changing the rest of the code.
I’ll explain why—but first I’ll just say that I understand that Point is used as an example because it is simple to understand and doesn’t take a lot of space on a page in a book. But there are other examples one could use that also satisfy those needs that, in addition, make sense as a motivation for using data abstraction. For example, a URL class, where you might initially have a representation that separated the components of a URL into protocol (enum)/site (string)/port (int)/path (string)/query (string) parameters and then switch to represent it as simple string, or vice versa. Easily understood as an example, a simple class to put in your book, and you might actually want to make that switch someday.
But back to the Point. The reasons you would never want to switch a Point representation from Cartesian to Polar, or vice versa, in your application without changing a line of your code is because the two representations have different semantics and performance. They are just not interchangable.