I don’t understand why we should even need to use public member vars.
Why can’t we always set them to private and use getters/setters instead? Being able to use functions where I can do more than access the variable seems to be always better than just accessing the variable directly and then finding out you need to change something later.
When is it prudent to ever use publics?
Fairly Subjective.
But assuming my very subjective perspectives on what seems to be good practice…
Sometimes it’s considered “prudent” when you are just using the class as a “Data Transfer Object” sometimes known as a “Value Object”. The very nature of these is that they are lean, and contain no behavior and only state. If you are unfamiliar with this pattern it basically just groups objects/primitives together into a container and that is its sole function.
Outside of that it seems be accepted practice that public member fields are ill-advised for the reasons you mentioned. Another reason is access control. Sometimes consumers should only be able to read a value, and it should only be able to be set locally. Using Getters/Setters allow you to do things like this. (Some languages also let you do some of this through const/read only fields that can be set once at initialization)
Fowler appears to put serialization functionality on the DTO itself, but one school of thought professes behavior shouldn’t exist on the fields of a DTO/Value Object.
http://martinfowler.com/eaaCatalog/dataTransferObject.html