Control de acceso.

Ya hemos visto un poco por encima que usando los modificadores de acceso 'private' y 'public' los elementos de una clase o una clase misma será visible o no desde otros puntos del programa. Vamos a completar los conocimientos relativos a todos los modificadores de acceso y el control de acceso en general, teniendo en cuenta que lo que viene a continuación es de especial importancia en la programación orientada a objetos.

El concepto de control de acceso hace referencia a ocultación de datos, que básicamente consiste en que no se pueda acceder directamente a los atributos de un objeto, sino que haya que hacerlo a través de las propiedades y métodos de una clase. Esto quiere decir que, de forma general, el usuario de la clase sólo tendrá acceso a una o más propiedades y/o métodos que le permitan acceder a los miembros privados, ignorando la disposición de éstos. De esta forma se consiguen dos objetivos:

1.- Que el usuario no tenga acceso directo a la estructura de datos interna de la clase, para que no pueda generar código basado en esa estructura, y así mantener inviolable la clase protegida.

2.- Que si en un momento determinado alteramos la definición de la clase, excepto el prototipo de las propiedades y métodos, todo el código escrito por el usuario basado en estas propiedades y métodos no tendrá que ser retocado.

Acceso privado.

Un miembro de una clase declarado privado con el modificador de acceso 'private' puede ser accedido por un objeto de esa clase sólo desde los métodos y propiedades de dicha clase. Esto significa que no puede ser accedido desde los métodos y propiedades de cualquier otra clase, incluidas las subclases.

public class Program
{
    public static void Main()
    {
        CircleClass circleClass = new CircleClass();
        double r = circleClass.radio; // Error: miembro privado de la clase 'CircleClass'.
    }
    public class CircleClass
    {
        private double radio;
    }
}

El compilador nos daría un error puesto que el atributo 'radio' perteneciente a la clase 'CircleClass' está declarado con el modificador de acceso 'private' y, por lo tanto, sólo es visible desde la propia clase 'CircleClass' y nunca desde fuera de ella.

Hay que tener en cuenta que de forma predeterminada, si no se especifica un modificador de acceso, el miembro declarado para a ser de manera automática declarado como 'private'. Sin embargo, y es mi opinión, considero que esta práctica no es aconsejable, y que siempre debes declarar el modificador de acceso, sea 'private' o sea cualquier otro.

Acceso protegido.

Un miembro de una clase declarado protegido con el modificador de acceso 'protected' se comporta de igual manera que uno declarado como privado para los métodos y propiedades de cualquier otra clase, excepto para los métodos y propiedades de sus subclases, para las cuales se comporta como si fuera un miembro público. Es poco ususal declarar miembros protegidos, pero realizando una programación avanzada en la cual haya implementaciones de clases derivadas, es posible que sea un recurso que debas utilizar con cierta frecuencia.

Acceso interno.

Un miembro de una clase declarado interno con el modificador de acceso 'internal' puede ser accedido por un objeto de esa misma clase en cualquier parte de la aplicación actual, o del ensamblado actual, donde el objeto en cuestión sea accesible. Esto se implementa con mucha frecuencia en aqueññas aplicaciones que estén construidas a base de ensamblados, o archivos '.dll', que no son más que conjuntos de clases agrupadas en un mismo ensamblado con extensión '.dll'. La construcción de aplicaciones a base de ensamblados es una de las organizaciones más productivas en programación en la plataforma .NET, y constituyen la mejor estrategia de diseño en vista a un mantenimiento fácil dividido por módulos.

public class Program
{
    public static void Main()
    {
        CircleClass circleClass = new CircleClass();
        double r = circleClass.Radio; // Correcto: miembro interno de la clase 'CircleClass'.
    }
    internal class CircleClass
    {
        private double radio;
        internal double Radio
        {
            get
            {
                return radio;
            }
            set
            {
                radio = value;
            }
        }
    }
}

Acceso público.

Un miembro de una clase declarado público con el modificador de acceso 'public' puede ser accedido desde un objeto de esa misma clase o en cualquier parte donde el objeto en cuestión sea accesible. En este caso no hay restricciones de acceso, pues los miembros públicos de una clase constituyen la interfaz pública de los objetos de esa clase. Además, también serán accesibles desde cualquier otro ensamblado de la misma aplicación.

public class Program
{
    public static void Main()
    {
        CircleClass circleClass = new CircleClass();
        double r = circleClass.Radio; // Correcto: miembro público de la clase 'CircleClass'.
    }
    public class CircleClass
    {
        private double radio;
        public double Radio
        {
            get
            {
                return radio;
            }
            set
            {
                radio = value;
            }
        }
    }
}

Acceso parcial.

Como norma general, una clase se define en un archivo, pero una clase, estructura, método o interfaz declarado público con el modificador de acceso 'partial' los autoriza a definirse en varios archivos. En algunos casos, como sucede con los formularios, Visual Studio gestiona una parte del código fuente que se genera automáticamente en un archivo por el diseñador de vista y deja al desarrollador la posibilidad de añadir la lógica en otro archivo. De esta manera, los dos archivs juntos componen la clase entera.

Por ejemplo, y en el caso de la creación a través de Visual Studio de un formulario de Windows Forms, el entorno de desarrollo integrado creará dos archivos separados que, juntos, completarán la clase que controla dicho formulario. Así, en primer lugar tendremos el archivo del formulario propiamente dicho ('archivo Form1.cs'), y en segundo lugar el archivo del código subyacente (archivo 'From1.Designer.cs'):

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
}

partial class Form1
{
    private System.ComponentModel.IContainer components = null;
    protected override void Dispose(bool disposing)
    {
        // ...
    }
    private void InitializeComponent()
    {
        // ...
    }
}

Al igual que en el caso del diseño de formularios con Windows Forms, en WPF (Windows Presentation Foundation) ocurre lo mismo. Hará un archivo de diseño del formulario en lenguaje XAML y otro archivo con el código subyacente en C# puro.

La palabra reservada 'this'.

Aunque la palabra reservada 'this' no es un modificador de acceso, la he incluido en esta sección porque es una herramienta más de control de acceso. Permite hacer referencia a la instancia actual, con lo cual se evitan ambigüedades entre, por ejemplo, una variable local y un parámetro de un método. Así, utilizando 'this' en el lugar apropiado cuando exista esta ambigüedad, Visual Studio ocultará todos los miembros que no correspondan a la instancia actual.

Con el tiempo comprobarás que la palabra reservada 'this' no es de uso frecuente y, personalmente, creo que siempre que se pueda hay que evitar cualquier tipo de ambigüedad entre nombres de miembros y, por lo tanto, evitar tener que utilizar 'this' para ocultar el miembro no deseado.

Por último, recuerda que no es posible utilizar 'this' para hacer referencia a un miembro estático, ya que 'this' sólo hace referencias a instancias de objetos y, como verás en la siguiente sección, no es posible crear instancias de miembros estáticos.