La aplicación más útil que encontré es con la implementación de fábricas. En muchos casos, es útil crear clases que sean mutables dentro de la fábrica pero inmutables a clases externas. Esto se puede implementar fácilmente en Java utilizando clases internas, haciendo que los campos y sus establecedores sean privados y solo exponiendo a los captadores como miembros públicos. Sin embargo, en C #, tuve que usar interfaces explícitas para lograr lo mismo. Explicaré más a fondo:
En Java, la clase interna Y la clase externa pueden acceder a miembros privados entre sí, lo que tiene mucho sentido ya que las clases están muy relacionadas. Están en el mismo archivo de código y probablemente los haya desarrollado el mismo desarrollador. Esto significa que la fábrica aún puede acceder a los campos y métodos privados en la clase interna para modificar sus valores. Pero las clases externas no podrán acceder a estos campos excepto a través de sus captadores públicos.
Sin embargo, en C #, las clases externas no pueden acceder a miembros privados de las clases internas, por lo que el concepto no es directamente aplicable. Utilicé una interfaz explícita como solución definiendo una interfaz privada en la clase externa e implementándola explícitamente en la clase interna. De esta manera, solo la clase externa puede acceder a los métodos en esta interfaz de la misma manera que se hace en Java (pero tienen que ser métodos, no campos).
Ejemplo:
public class Factory
{
// factory method to create a hard-coded Mazda Tribute car.
public static Car CreateCar()
{
Car car = new Car();
// the Factory class can modify the model because it has access to
// the private ICarSetters interface
((ICarSetters)car).model = "Mazda Tribute";
return car;
}
// define a private interface containing the setters.
private interface ICarSetters
{
// define the setter in the private interface
string model { set; }
}
// This is the inner class. It has a member "model" that should not be modified
// but clients, but should be modified by the factory.
public class Car: ICarSetters
{
// explicitly implement the setter
string ICarSetters.model { set; }
// create a public getter
public string model { get; }
}
}
class Client
{
public Client()
{
Factory.Car car = Factory.CreateCar();
// can only read model because only the getter is public
// and ICarSetters is private to Factory
string model = car.model;
}
}
Para eso usaría interfaces explícitas.