Предоставляя методы доступа (методы установки / получения или использование свойств в языках, которые их поддерживают, например C #), разработчик может определить более стабильный контракт между классом и его пользователями. Вместо прямого доступа к полю, фактически читая или записывая область памяти, пользователь вынужден вызывать метод, который, в свою очередь, может инкапсулировать любую необходимую логику.
В свою очередь, при изменении внутреннего дизайна класса его контракт нужно менять реже. Следовательно, удобство сопровождения и стабильность кода улучшены.
Обратите внимание, что производительность не является проблемой, поскольку современные JIT-компиляторы способны оптимизировать вызовы тривиальных методов получения / установки таким образом, что фактический вызов исключается, а код эквивалентен прямому доступу к базовой области памяти.
Edit:
Кроме того, сеттер и геттер обычно могут иметь различную видимость (публичную / защищенную / приватную), обеспечивая дополнительное преимущество более детального управления операциями чтения / записи над указанным значением.
Следовательно, лучше всего избегать открытых полей, где это возможно, и использовать вместо них методы или свойства метода установки / получения.