Instrucciones de uso de clases base
Una clase es uno de los tipos más común. Las clases pueden ser abstractas o selladas. Una clase abstracta requiere una clase derivada para proporcionar una implementación. Una clase sealed no admite una clase derivada. Es conveniente utilizar clases, en vez de otros tipos.
Las clases base son una forma útil de agrupar objetos que comparten un conjunto común de funcionalidades. Las clases base pueden proporcionar un conjunto predeterminado de funcionalidades a la vez que permiten la personalización mediante la ampliación.
Se debería proporcionar un constructor de forma explícita para todas las clases, ya que, normalmente, los compiladores agregan un constructor público predeterminado a las clases que no definen un constructor. Si la intención es que la clase no se pueda crear, el hecho de que contenga dicho constructor público predeterminado puede resultar confuso para los usuarios de ésta. Por lo tanto, lo mejor es definir siempre al menos un constructor por clase. Si no se desea que ésta se pueda crear, se puede configurar el constructor como privado.
Debe agregar extensibilidad o polimorfismo al diseño sólo si tiene un escenario del cliente claro. Por ejemplo, proporcionar una interfaz para adaptadores de datos es complicado y no ofrece beneficios reales. Además, los programadores deberán programar específicamente cada adaptador, por tanto, el beneficio que proporciona una interfaz es mínimo. Sin embargo, no es necesario que sean coherentes entre todos los adaptadores. Aunque una interfaz o clase abstracta no es lo apropiado en esta situación, es muy importante proporcionar un modelo coherente. Se pueden proporcionar modelos coherentes para programadores en las clases base. Siga estas instrucciones para crear clases base.
Clases base e interfaces
Un tipo de interfaz es una especificación de un protocolo, potencialmente compatible con muchos tipos de objetos. Utilice clases base en vez de interfaces siempre que sea posible. Desde la perspectiva de las versiones, las clases son más flexibles que las interfaces. Con una clase, se puede incluir la versión 1.0 y, a continuación, en la versión 2.0 agregar un nuevo método a la clase. Siempre que el método no sea abstracto, las clases derivadas existentes seguirán funcionando sin sufrir ningún cambio.
Como las interfaces no son compatibles con la herencia de implementación, el modelo aplicado a las clases no se aplica a las interfaces. Agregar un método a una interfaz es lo mismo que agregar un método abstracto a una clase base; cualquier clase que implemente la interfaz interrumpirá la ejecución porque la clase no implementa el nuevo método.
La utilización de interfaces es adecuada en las situaciones siguientes:
- Hay varias clases no relacionadas que son compatibles con el protocolo.
- Estas clases ya han establecido clases base (por ejemplo, algunas son controles de interfaz de usuario (UI) y otras son servicios Web XML).
- La agregación no es adecuada o no es viable.
En el resto de las situaciones, es mejor utilizar el modelo de herencia de clases.
Constructores y métodos protegidos
Proporcione la personalización de clases a través de métodos protegidos. La interfaz pública de una clase base debe proporcionar un conjunto completo de funcionalidades para el consumidor de la clase. Sin embargo, los usuarios de la clase a menudo desean implementar el menor número de métodos posible y, de este modo, proporcionar el conjunto completo de funcionalidades al consumidor. Con esta finalidad, proporcione un conjunto de métodos públicos finales o no virtuales que llaman a través de un único método protegido que proporciona implementaciones para los métodos. Este método se debe marcar con el sufijo Impl
. La utilización de este modelo también proporciona lo que se conoce como método Template. En el siguiente ejemplo de código se muestra este proceso.
Public Class SampleClass
Private x As Integer
Private y As Integer
Private width As Integer
Private height As Integer
Private specified As BoundsSpecified
Overloads Public Sub SetBounds(x As Integer, y As Integer, width As
Integer, height As Integer)
SetBoundsImpl(x, y, width, height, Me.specified)
End Sub
Overloads Public Sub SetBounds(x As Integer, y As Integer, width As
Integer, height As Integer, specified As BoundsSpecified)
SetBoundsImpl(x, y, width, height, specified)
End Sub
Protected Overridable Sub SetBoundsImpl(x As Integer, y As Integer,
width As Integer, height As Integer,
specified As BoundsSpecified)
' Insert code to perform meaningful operations here.
Me.x = x
Me.y = y
Me.width = width
Me.height = height
Me.specified = specified
Console.WriteLine("x {0}, y {1}, width {2}, height {3}, bounds {4}",
Me.x, Me.y, Me.width, Me.height, Me.specified)
End Sub
End Class
[C#]
public class MyClass
{
private int x;
private int y;
private int width;
private int height;
BoundsSpecified specified;
public void SetBounds(int x, int y, int width, int height)
{
SetBoundsImpl(x, y, width, height, this.specified);
}
public void SetBounds(int x, int y, int width, int height,
BoundsSpecified specified)
{
SetBoundsImpl(x, y, width, height, specified);
}
protected virtual void SetBoundsImpl(int x, int y, int width, int
height, BoundsSpecified specified)
{
// Add code to perform meaningful opertions here.
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.specified = specified;
}
}
Si no incluye un constructor public o protected, la mayoría de los compiladores, como el de C#, insertarán uno. Por tanto, para una mejor documentación y legibilidad del código fuente, deberá definir explícitamente un constructor protected en todas las clases abstractas.
Instrucciones de uso de clases sealed
Utilice clases sealed si sólo hay propiedades y métodos estáticos en una clase.
Vea también
Instrucciones de diseño para programadores de bibliotecas de clases | Instrucciones de uso de tipos | Instrucciones de nomenclatura de clases