2011-01-11 23 views
6

Esto se considera upcasting correcto?¿Cuándo y por qué elevaría un objeto?

Derived d = new Derived(); 
Base b = d; // Always OK. 

¿Por qué alguien upcast? ¿Cuando? ¿Es porque debemos convertir el objeto en la clase base para que no tenga la funcionalidad de la clase derivada?

¿Cómo se ve este código en la memoria? Las instancias de clases derivadas y la memoria se crean para ese objeto. A continuación, se crea un objeto de clase base que hace referencia a d ahora.

+0

Son útiles, porque a veces no te importa lo que eres objeto 'Derived', solo necesitas métodos genéricos en' Base', por ejemplo para objetos DB, donde necesitas guardar, que es lo mismo para todos los objetos DB, independientemente de otros detalles – PostMan

Respuesta

9

Creo que puede estar un poco confundido acerca de lo que hace la subida. El upcast no deshabilita la funcionalidad del objeto derivado, ni crea un nuevo objeto Base. Por el contrario, solo se necesita una vista más limitada del objeto que ha subido. A través de la referencia de la clase base, puede acceder solo a los métodos declarados en Base, pero si cualquiera de esos métodos se reemplaza en la clase derivada, invocarlos a través de la referencia base seguirá llamando a la versión derivada.

En cuanto a cuando usted quisiera hacer esto, es raro ver a la gente remontándose sin ningún motivo en particular. Después de todo, eso limita lo que puedes hacer con el objeto. Sin embargo, como han señalado otros carteles, es común aumentar implícitamente al pasar un objeto a una función o devolver un objeto desde una función. En esos casos, la actualización permite a los autores de las funciones tomar un parámetro con el conjunto de requisitos más débil necesario para realizar el trabajo o devolver un objeto de una función que exhibe un conjunto de comportamientos sin revelar necesariamente el tipo completo del objeto.

3

Los reenvíos son normales porque cada Derived es .

Cuando se escribe una clase B que se hereda de una clase A, entonces B es una subclase de A. Esto significa que se puede utilizar un objeto de tipo B en cualquier lugar que se puede utilizar un objeto de tipo A.

Deberías leer acerca de inheritance y qué tan poderoso es.

+0

¿Cuándo le gustaría actualizar el código? ¿Por qué? Sí Derived is Base, pero ¿ahora qué? – RoR

+2

@RoR significa que puede escribir código compartido que funcione con Base, y cada clase que derive de base podrá usar este código compartido. –

1

Cuando se desea utilizar polymorphism puede utilizar conversión hacia arriba, por ejemplo, tiene un método que acepta Base, pero te gusta llamarlo con su Derived:

public void DoAction(Base base) 
{ 
// do stuff 
} 

DoAction(drivedItem); 

DoAction(baseItem); 

tanto de las llamadas anteriores son ciertas.

pero en el polimorfismo no se puede hacer downcasting se puede utilizar, por ejemplo, la sobrecarga de métodos para superar sus problemas.

+0

En el polimorfismo no OO, puede abatir utilizando, por ejemplo, la coincidencia de patrones ;-) –

0

No estoy seguro de que iba a escribir un código como el ejemplo muy a menudo, pero una aplicación de este tipo de fundición sería método llama:

void Test() 
{ 
    Derived d = new Derived(); 
    this.DoSomething(d); 
} 

void DoSomething(Base b) 
{ 
    // something 
} 

En este caso, d no es "resultó en "un objeto Base, simplemente se trata como uno". No sé con certeza, pero imagino que la memoria real asociada con el objeto d no cambia en absoluto.

1

¿Es porque debemos convertir el objeto en la clase base por lo que no tiene la funcionalidad de la clase derivada?

Porque hay alguna pieza de código que funciona independientemente de si su objeto es Derived1 o Derived2 y se escribe sólo se basa en la suposición de que es compatible con la funcionalidad Base. Esto se llama abstracción y dará como resultado la reutilización del código. No tiene que volver a escribir esa función para Derived1 y Derived2 por separado. Se abstraen los detalles específicos de Derived1 y Derived2.

Por cierto, muchas veces, no haces el reparto explícitamente. Simplemente aprovecha este hecho cuando pasas una instancia a una función.Por ejemplo, cuando se agrega un string a un ArrayList, que implícitamente echarlo a su tipo base object porque la firma de Add es:

void Add(object o); 
0

En cuanto a su segunda pregunta (como se ven en la memoria), ambos se ve igual en la pila. En la pila, ambos son simples consejos para el montón.

0

Razón Uno: Si escribo código en 2008 que sabe acerca de la clase Base y hace algunas cosas con él que sólo implican la funcionalidad de esa clase, upcasting le permite crear la clase Derived en 2011 y pasar una instancia de mi código sin ningún cambio.

Podría decirse que esto también podría hacerse (y tal vez más) si hubiera escrito mi código usando genéricos en primer lugar.

Motivo Dos: si necesita almacenar varias instancias de clases diferentes en un solo contenedor, necesita convertir esas instancias a una clase base compartida. Considere, por ejemplo, una lista de fuentes de datos "actualmente cargadas" que pueden ser archivos locales, direcciones URL, datos en memoria e incluso zócalos; todas estas serían clases específicas que comparten una clase de origen de datos común.

Cuestiones relacionadas