Clases y c Abstract ++
C ++ soportes el enlace, que es cuando se resuelve una llamada a un método basado en el tipo de tiempo de ejecución (o tipo dinámico) del objeto de destino en lugar de su tipo declarado (o tipo estático). Esto se demuestra en el siguiente fragmento de código C ++:
#includeusing namespace clase std Horno {public: virtual void cocinero () {cout lt; lt; "Cocinar con un horno" lt; lt; endl -}} - clase homo de microondas: public Horno {public: virtual void cocinero () {cout lt; lt; "Cocinar con un horno de microondas" lt; lt; endl -}} - vacío prepareMeal (Horno horno) {oven.cook () -}
En la función de prepareMeal (), la llamada a oven.cook () puede pasar a Horno :: cocinar () o Homo de microondas :: cocinar () dependiendo del tiempo de ejecución (el "real") tipo de horno objeto pasó.
los virtual palabra clave es crítica aquí. Sin ella, el cocinar() método estaría obligado temprano, según el tipo en tiempo de compilación, e invocar Horno :: cocinar () cada vez. Una vez declarado virtual en el Estufa clase, el método se supone que es virtual en cada subclase pero no está de más repetir la declaración para que los lectores entiendan.
El siguiente programa simple demuestra este principio en la práctica:
int main () {Horno horno-prepareMeal (horno) -MicrowaveOven mo-prepareMeal (mo) -Retorno 0-}
En este programa, la llamada a cocinar() genera dos salidas diferentes dependiendo del tipo de horno:
Cocinar con un ovenCooking con un horno de microondas
No siempre es el caso, que un método en la clase base puede ser definido. Considera el Estufa mayúsculas y con más cuidado. Hay un número de diferentes tipos de hornos - hornos convencionales, hornos de convección y hornos de microondas -, pero se podría argumentar que no hay horno real que no pertenece a una de estas subclases. Usted puede ser capaz de decir cómo los diferentes tipos de hornos realizan la cocinar operación - que es, lo que es un ConventionalOven :: cocinar () y un Homo de microondas :: cocinar () debe hacer puede ser definido. Probablemente no sea posible definir qué acciones Horno :: cocinar () debe llevar a cabo.
Usted no puede simplemente dejar Horno :: cocinar () no declarada en un lenguaje fuertemente tipado como C ++. Sin embargo, usted puede declarar un método, sino dejarlo sin aplicarse si no existe ninguna aplicación. Uno utiliza la siguiente sintaxis curiosa de hacerlo:
clase Horno {public: virtual void cocinero () = 0 -} -
Este código declara un método Estufa::cocinar() que está obligado tarde, pero no implementa el método. De hecho, va más allá al decir que no se llevará a cabo el método. En C ++, se dice que tal método sea virtual pura. Programadores de C ++ también utilizan el término preferido en muchos otros lenguajes de programación inflexible de tipos: abstracto. los Estufa clase se dice que es abstracto.
Un resumen representa una propiedad que usted sabe la clase posee, pero no saben cómo poner en práctica de forma inequívoca en la clase actual.
Una clase abstracta es si contiene uno o más métodos virtuales puras. La importancia de esto es que no se puede crear una instancia de una clase abstracta. Así, el siguiente ya no está permitido:
int main () {Horno horno-prepareMeal (horno) -Retorno 0-}
La razón de esto es muy simple: si ha creado un objeto de clase Estufa y luego trató de invocar oven.cook (), ¿qué debe hacer el compilador?
A un nivel más filosófico, está bien decir que no es un término común que se llama Estufa que describe los hornos convencionales y hornos de microondas y hornos de convección. Este termino Estufa es un concepto habitual porque se une a las similitudes en todas estas subclases. Pero no hay ninguna instancia de un horno que no es una de las subclases de Estufa.
Una subclase de una clase abstracta es en sí misma abstracta hasta que todos los métodos virtuales puros han sido anulado por no abstracto (es decir, hormigón) Versiones. Así, la clase Horno de microondas en el fragmento de código anterior no es abstracto - incluso si Estufa eran abstracta - porque anula cocinar() con su propia versión de concreto.
Tenga en cuenta que no hay nada malo con la función prepareMeal () se define como sigue:
anular prepareMeal (Horno horno) {oven.cook () -}
A pesar de que el argumento se declara ser un Estufa, sólo puede ser invocada con alguna subclase de Estufa, como Horno de microondas o Horno convencional, para cual cocinar() se define.