Comme indiqué par d'autres, les variables privées sont utiles pour éviter les utilisations erronées, ce qui pourrait rendre l'état de l'objet incohérent et rendre difficile le suivi des bogues et des exceptions imprévues.
Mais dans l’autre côté, ce qui a été en grande partie ignoré concerne les champs protégés.
Une sous-classe étendue aura un accès complet aux champs protégés, rendant l'objet aussi fragile que si ces champs étaient publics, mais cette fragilité est limitée à la classe étendue elle-même (à moins qu'elle ne les expose encore plus).
Il est donc difficile de considérer que les champs publics sont bons, et à ce jour, la seule raison de les utiliser est celle des classes utilisées comme paramètre de configuration (une classe très simple avec de nombreux champs et aucune logique, de sorte que la classe est passée en paramètre uniquement à une méthode).
En revanche, les champs privés réduisent la flexibilité de votre code pour les autres utilisateurs.
Flexibilité vs problèmes, avantages et inconvénients:
Les objets instanciés par votre code dans la classe vanilla avec des champs protégés sont en sécurité et relèvent de votre entière responsabilité.
D'autre part, les objets étendant votre classe avec des champs protégés, instanciés par les utilisateurs de votre code, relèvent de leur responsabilité et non de la vôtre.
Par conséquent, les champs / méthodes protégés mal documentés, ou si les utilisateurs ne comprennent pas vraiment comment ces champs et méthodes doivent être utilisés, risquent de causer des problèmes inutiles à eux-mêmes et à vous-même.
D'un autre côté, rendre la plupart des choses privées réduira la flexibilité des utilisateurs et les mettra peut-être même à la recherche d'alternatives maintenues, car ils ne voudront peut-être pas créer et maintenir une fourchette juste pour que les choses se passent bien.
Donc, ce qui compte vraiment, c'est un bon équilibre entre privé, protégé et public.
Maintenant, décider entre privé et protégé est le vrai problème.
Quand utiliser protégé?
Chaque fois que vous comprenez qu'un champ peut être très flexible, il doit être codé comme protégé. Cette flexibilité est la suivante: de devenir null (où null est toujours vérifié et reconnu comme un état valide ne générant pas d'exceptions), à avoir des contraintes avant d'être utilisé par votre classe ex. > = 0, <100, etc., et fixé automatiquement pour les valeurs de dépassement / de sous-débit, générant tout au plus un message d'avertissement.
Donc, pour un tel champ protégé, vous pouvez créer un getter et l’utiliser uniquement (au lieu d’utiliser directement la variable de champ), alors que d’autres utilisateurs ne peuvent pas l’utiliser, s’ils veulent plus de flexibilité pour leur code spécifique, dans mon exemple, pourrait ressembler à : s'ils veulent que les valeurs négatives fonctionnent correctement dans leur classe étendue.