Une classe, comme définie précédemment, est un ensemble de membres typés (méthodes et attributs) qu'on est forcément amené à manipuler. Si p est une instance de Point(a,b) où a et b sont de type int, on accède aux membres de p comme ceci :
La question qui vient tout de suite à l'esprit est la suivante : pourquoi définir une méthode getX(), alors qu'on peut accéder directement aux champs x et y de la classe Point ?
En fait, lorsqu'on est amené à manipuler de nombreuses classes ainsi que de nombreuses relations entre ces classes (cf. héritage), le schéma, les données et les opérations peuvent devenir très complexes (surtout pour un individu n'ayant pas conçu le code). On a donc recours à un mécanisme qu'on appelle encapsulation des données, lequel se charge de masquer à certaines parties du programme les champs de la classe dans un souci d'intégrité. L'utilisateur est donc amené à ne manipuler que des méthodes qui ont été approuvées et qui en théorie remplissent bien leur rôle.
Selon le principe d'encapsulation, les méthodes ont un accès public - cela signifie que tout élément d'un programme peut utiliser une méthode. Quant aux attributs composant l'état, ils ont un accès privé (private) - seul l'objet lui-même (et donc les méthodes qu'il contient) a un accès direct à ses attributs. Dans ce cas, le seul moyen d'accéder à ces attributs est d'utiliser les méthodes de l'objet. Les attributs ne peuvent pas être utilisés directement par un autre élément du programme ni même un autre objet, même si cet objet est de la même classe. Autre point : tous les attributs d'un objet qui sont hérités sont directement accessibles par les autres membres de cet objet.
En ce qui concerne les dernières remarques, il y a souvent confusion sur la sémantique de l'accès privé. Le principe d'encapsulation implique une protection des attributs que nous appellerons verticale (seuls l'objet lui-même et les objets d'une sous-classe y ont accès). Nous retrouvons cette sémantique dans des langages comme Smalltalk, Oz ou OCaml. Cependant certains langages, comme C++, Pascal ou Java, plaident pour une protection des attributs que nous appellerons horizontale (les objets d'une même classe y ont accès, mais pas les objets des sous-classes).
Certains langages proposent de changer le type d'accès des membres d'un objet. Cette opération s'effectue au sein des classes de ces objets. Par exemple, le C++ et le Pascal proposent les visibilités suivantes :
La sémantique de ces visibilités et leur nombre varient selon le langage. Par exemple, Java propose une définition un peu différente pour les membres protégés (elle s'étend à l'ensemble des objets de la même classe, des classes filles et des classes du même paquetage). Python propose aussi la possibilité de modifier la visibilité des membres d'une classe en préfixant le nom du membre par le caractère souligné ('_'). Par exemple, getX() est une méthode public, _getX() est seulement utilisable par les éléments du même module et __getX() est privé.