En la programación basada en clases , el downcasting o el refinamiento de tipos es el acto de lanzar una referencia de una clase base a una de sus clases derivadas.
En muchos lenguajes de programación , es posible verificar a través de la introspección de tipos para determinar si el tipo del objeto referenciado es realmente el que se está convirtiendo o un tipo derivado del mismo, y así emitir un error si no es el caso.
En otras palabras, cuando una variable de la clase base (clase principal ) tiene un valor de la clase derivada ( clase secundaria ), es posible la degradación.
Ejemplos de
Java
pública clase de frutas {} clase padre // pública clase de Apple se extiende de frutas {} // clase hijapublic static void main ( String args [] ) { // Lo siguiente es un upcast implícito: Fruit parent = new Apple (); // Lo siguiente es un abatido. Aquí, funciona ya que la variable `parent` // contiene una instancia de Apple: Apple child = ( Apple ) parent ; }
C ++
// Clase padre: class Fruit { public : // Debe ser polimórfica para usar la conversión dinámica comprobada en tiempo de ejecución. virtual ~ Fruit () = predeterminado ; };// Clase hija: clase Apple : public Fruit {};int main ( int argc , const char ** argv ) { // Lo siguiente es un upcast implícito: Fruit * parent = new Apple (); // Lo siguiente es un abatido. Aquí, funciona ya que la variable `parent` // contiene una instancia de Apple: Apple * child = dynamic_cast < Apple *> ( parent ); }
Usos
Downcasting es útil cuando se conoce el tipo de valor al que hace referencia la variable principal y, a menudo, se utiliza cuando se pasa un valor como parámetro. En el siguiente ejemplo, el método objectToString toma un parámetro Object que se supone que es de tipo String.
public static String objectToString ( Object myObject ) { // Esto solo funcionará cuando el myObject que actualmente tiene el valor es string. return ( String ) myObject ; }public static void main ( String args [] ) { // Esto funcionará ya que pasamos String, por lo que myObject tiene el valor String. Resultado de cadena = objectToString ( "Mi cadena" ); Objeto iFail = nuevo Objeto (); // Esto fallará ya que pasamos en Object que no tiene el valor de String. resultado = objectToString ( iFail ); }
En este enfoque, la conversión descendente evita que el compilador detecte un posible error y, en su lugar, provoca un error en tiempo de ejecución. Downcasting myObject to String ('(String) myObject') no fue posible en tiempo de compilación porque hay ocasiones en que myObject es de tipo String, por lo que solo en tiempo de ejecución podemos averiguar si el parámetro pasado es lógico. Si bien también podríamos convertir myObject en un String en tiempo de compilación usando el java.lang.Object.toString () universal, esto correría el riesgo de llamar a la implementación predeterminada de toString () donde no fue útil o inseguro, y el manejo de excepciones no pudo evitar esto .
En C ++, la verificación de tipos en tiempo de ejecución se implementa a través de dynamic_cast . Static_cast implementa el downcasting en tiempo de compilación , pero esta operación no realiza ninguna verificación de tipo. Si se usa incorrectamente, podría producir un comportamiento indefinido.
Crítica
Algunos idiomas, como OCaml , no permiten el abatimiento por completo. [1]
Un ejemplo popular de un diseño mal considerado es contenedores de los mejores tipos , [ cita requerida ] como los Java contenedores antes genéricos de Java se introdujeron, que requiere downcasting de los objetos contenidos para que puedan ser utilizados de nuevo.
Ver también
Referencias
- ^ Vouillon, Jérôme; Rémy, Didier; Garrigue, Jacques (12 de septiembre de 2013). "Objetos en OCaml" . La versión 4.01 del sistema OCaml: Documentación y manual del usuario .
enlaces externos
- Downcasting is a Code Smell por Jeremy D. Miller
- Una tragedia abatida por Jimmy Bogard
- Prefiere el polimorfismo sobre la instancia de y el downcasting de Bill Venners
- Downcasting en C # por Scott Lysle
- Varias técnicas de abatimiento
- Upcasting, downcasting de Sinipull