Maneras de estructurar una aplicación Visual Basic .Net
Tipos personalizados de variables
Enumeraciones
Una enumeración es un tipo especial de variable numérica en la que los valores que dicha variable puede tomar, son constantes simbólicas, es decir que en lugar de usar un número, se usa una palabra (constante) que hace referencia a un número.
Enum colores
rojo = 1
azul
verde
End Enum
Pueden declararse dentro de una clase, un módulo o un espacio de nombres, siempre fuera de cualquier procedimiento.
Pueden aplicarsele modificadores de ámbito.
Por defecto el tipo es Integer, pero las enumeraciones también pueden ser de tipo Byte, Long o Short, para poder especificar un tipo diferente a Integer, lo indicaremos usando As Tipo después del nombre de la enumeración.
En caso de que no indiquemos ningún valor, el primero será cero y los siguientes valdrán uno más que el anterior
La asignación podemos hacerla en cualquier momento, en el siguiente caso, rojo valdrá cero, azul tendrá el valor 3 y verde uno más que azul, es decir 4.
Enum colores
rojo
azul = 3
verde
End Enum
Los valores que podemos asignar a los elementos (o miembros) de una enumeración serán valores que estén de acuerdo con el tipo de datos.
Estructuras
Las estructuras son parecidas a las enumeraciones pero con muchas ventajas, entre ellas que cada elemento de la estructura puede ser de cualquier tipo integer, double, String o matriz, además, se pueden declaran funciones dentro de la estructura, constructores, ámbito de variables independientes. Etc. Las estructuras son tipos de valor
Una declaración de estructuras empieza con la instrucción Structure, y finaliza con la instrucción End Structure. Entre estas dos instrucciones debe declararse por lo menos un miembro.
Structure Empleado
Public Nombre As String
Public Extension As Long
Private Salario As Decimal
End Structure
Visual Basic .NET unifica la sintaxis para clases y estructuras, y el resultado es que ambas entidades admiten prácticamente las mismas características. No obstante, existen también importantes diferencias entre clases y estructuras.
Similitudes
Las estructuras y las clases son similares en los siguientes aspectos:
Ambas tienen miembros, incluyendo constructores, métodos, propiedades, campos, constantes, enumeraciones y eventos.
Ambas pueden implementar interfaces.
Ambas pueden tener constructores compartidos, con o sin parámetros.
Diferencias
Las estructuras y las clases difieren en los siguientes aspectos:
Las estructuras son tipos de valor, las clases son tipos de referencia.
Las estructuras utilizan asignación de pila y las clases utilizan asignación del montón.
De forma predeterminada, todos los miembros de estructura son Public y las variables y constantes de clase son Private, mientras que otros miembros de clase son Public de forma predeterminada. Este comportamiento de los miembros de las clases proporcionan compatibilidad con el sistema de valores predeterminados de Visual Basic 6.0.
Los miembros de estructuras no pueden declararse como Protected, a diferencia de los miembros de clase.
Los procedimientos de las estructuras no pueden controlar eventos, a diferencia de los procedimientos de clase.
Las declaraciones de variables de estructura no pueden especificar inicializadores, la palabra clave New o los tamaños iniciales para matrices; mientras que las declaraciones de variables de clase sí pueden.
Las estructuras heredan de forma implícita de la clase ValueType, no pueden heredar de ningún otro tipo de clase. Las clases pueden heredar de cualquier clase o clases que no sean del tipo ValueType.
Las estructuras no son heredables; las clases, sí.
Las estructuras no se terminan nunca, por lo tanto, Common Language Runtime (CLR) nunca llama al método Finalize en una estructura; las clases las termina el recolector de elementos no utilizados, que llama al método Finalize en una clase cuando detecta que no quedan referencias activas.
Las estructuras sólo pueden tener constructores no compartidos si pueden tomar parámetros; sin embargo las clases pueden tener constructores con o sin parámetros.
Cada estructura tiene un constructor público implícito sin parámetros. El constructor inicializa todos los miembros de datos de estructura con sus valores predeterminados. Este comportamiento no puede redefinirse.
Puede asignar el valor Nothing a una variable de estructura; aunque la instancia sigue asociada con la variable.
Espacios de nombres
Las aplicaciones .NET se ejecutan en lo que se llama "dominio de la aplicación" que es como un espacio donde se ejecuta nuestra aplicación y está aislada del resto de las aplicaciones que se están ejecutando en Windows.
Un espacio de nombres es una forma de agrupar clases, funciones, tipos de datos, etc. que están relacionadas entre sí.
Pero el que distintos espacios de nombres pertenezcan a un mismo Namespace no significa que todos estén dentro de la misma librería o assembly. Un Namespace puede estar repartido en varios assemblies o librerías. Por otro lado, un assembly, (o ensamblado), puede contener varios Namespaces.
Pero de esto no debemos preocuparnos, ya que el IDE de Visual Studio .NET se encarga de "saber" en que assembly está el Namespace que necesitamos.
Namespace CursoGuille
Namespace Entrega16
Module Module1
Sub Main()
End Sub
End Module
End Namespace
End Namespace
Ensamblados (Funcionamiento de .Net, no es necesario conocerlo)
"Los ensamblados componen la unidad fundamental de implementación, control de versiones, reutilización, ámbito de activación y permisos de seguridad en una aplicación basada en .NET. Los ensamblados adoptan la forma de un archivo ejecutable (.exe) o un archivo de biblioteca de vínculos dinámicos (.dll), y constituyen unidades de creación de .NET Framework. Proporcionan a Common Language Runtime la información que necesita para estar al corriente de las implementaciones de tipos. Un ensamblado puede entenderse como una colección de tipos y recursos que forman una unidad lógica de funcionalidad y que se generan para trabajar conjuntamente"
Para que nos entendamos, podríamos decir que un assembly es una librería dinámica (DLL) o programa ejecutable en la cual pueden existir distintos espacios de nombres. Aunque esto es simplificar mucho, por ahora nos vale.
Un ensamblado o assembly puede estar formado por varios ficheros DLLs y EXEs, pero lo más importante es que todos los ensamblados contienen un manifiesto (o manifest), gracias al cual se evitan muchos de los quebraderos de cabeza a los que Windows nos tiene acostumbrados, al menos en lo referente a las distintas versiones de las librerías y ejecutables. Este manifiesto es una tabla de contenido del Assembly que lo identifica y dice su versión y otros datos. Esta información elimina lo que en otras versiones se llamaba "infierno de las DLL" por los enormes problemas de versiones y conflictos que generaban.
Por ejemplo, supongamos que tenemos una librería DLL que en su primera versión contenía X funciones. Al tiempo, se crea la segunda versión de dicha librería en la que se cambian algunas funciones y se añaden otras nuevas, para mejorar el rendimiento de las funciones contenidas en esa librería se usa otra DLL que es usada por algunas de las funciones contenidas en esa segunda versión. Esa otra librería puede ser una librería del sistema, la cual a su vez se actualiza con nueva funcionalidad y puede que dicha funcionalidad dependa a su vez de una tercera librería.
Resulta que instalamos un programa que usa las últimas versiones de todas estas librerías. Todo va bien, el programa funciona a las mil maravillas y nosotros estamos muy satisfechos de ese programa que no se cuelga ni una sola vez... Ahora llega a nuestras manos otra aplicación que necesitamos instalar y la instalamos, pero resulta que esa aplicación usa la primera versión de nuestra famosa librería. Si el programa de instalación está bien hecho, no ocurrirá nada malo, ya que al descubrir que tenemos una versión más reciente de la librería, deja la que ya está instalada. Probamos el programa de todo funciona bien. Probamos el maravilloso programa anterior y también funciona bien. ¿Cual es el problema? Por ahora ninguno, pero espera...
Después instalamos un programa que usa una de las librerías del sistema u otra que también usa nuestra "flamante" librería, pero ese programa se ha instalado de "mala manera", bien porque el programa de instalación sea malo o bien porque simplemente se ha instalado mal... como quiera que ha instalado una librería anterior a la que nuestros dos maravillosos ejecutables usan, se puede dar el caso de que ninguno de los dos programas funcionen correctamente... esto ocurrió cuando salió el Internet Explorer 4 y causó no pocos problemas... aunque también ha ocurrido con otros programas que no han tenido en cuenta a la hora de instalar que ya existe una versión más reciente de la librería. Por suerte, esto ya es menos común que hace unos años, sobre todo si los programas de instalación están creados con el Windows Installer o estamos usando el Windows 2000/XP.
Pero es que .NET mejora aún esa "imposibilidad" de meter la pata ya que cada assembly contiene un manifiesto en el cual se indica:
- Nombre y la versión del assembly
- Si este assembly depende de otros ensamblados, con lo cual se indica hasta la versión de dichos ensamblados
- Los tipos expuestos por el assembly (clases, etc.)
- Permisos de seguridad para los distintos tipos contenidos en el assembly.
- Datos del copyright, etc.
Nuevamente hay que comentar que no hay que preocuparse mucho de esto, ya que es el propio .NET el que se encarga de que todo funcione correctamente (al menos a priori)
La ventaja de los ensamblados es que "realmente" no necesitan de una instalación y un registro correcto en el registro del sistema de Windows, ya que es el "intérprete" de .NET el que se encarga de hacer las comprobaciones cuando tiene que hacerlas. Por tanto podríamos distribuir una aplicación sin necesidad de crear un programa de instalación. Pero, (¿por qué siempre hay un pero?), si la aplicación usa ensamblados compartidos, puede que sea necesario usar una instalación.
Los ensamblados compartidos se pueden usar por varias aplicaciones diferentes y deben estar "debidamente" instalados en el directorio asignado por el propio .NET Framework.
Ejemplo de ensamblados compartidos son los que definen las clases (tipos) usados por el propio .NET Framework.
Clases abstractas e interfaces en Visual Basic .Net
Clases Abstractas
Una clase abstracta es la que contiene métodos que las clases derivadas deben implementar, pero no la misma clase base. Un método abstracto es un método vacío, sin implementación. En lugar de eso, las clases derivadas deben proporcionar una implementación. Una clase abstracta es una clase que puede obtener miembros abstractos, aunque no se requiera hacerlo de esta forma.
Cualquier clase que contenga miembros abstractos debe ser abstracta.
Una clase abstracta también puede contener miembros no abstractos.
No es posible crear la instancia directamente de una clase abstracta. En este sentido, las clases abstractas son como las interfaces.
Las clases abstractas se usan para proporcionar implementaciones parciales de clase que pueden completar las clases concretas derivadas. Las clases abstractas son particularmente útiles para proporcionar una implementación parcial de una interfaz que puede ser reutilizada por varias clases derivadas. Se declaran utilizando la palabra clave MustInherit.
El siguiente ejemplo muestra cómo crear una clase abstracta Animal con un método Comer, y cómo generarlo para crear una clase Perro.
Public MustInherit Class Animal
Public MustOverride Sub Comer()
End Class
Public Class Perro : Inherits Animal
Public Overrides Sub Comer()
'…
'…
End Sub
End Class
Puede crear un método abstracto en una clase abstracta usando la palabra clave MustOverride. Una clase abstracta puede declarar un método abstracto, pero no puede declarar una clase no abstracta.
Interfaces
Una interfaz especifica un contrato sintáctico y semántico al cual se deben adherir todas las clases derivadas. Específicamente, una interfaz describe la parte del what (qué) del contrato, y las clases que implementan la interfaz describen la parte del how (cómo) del mismo.
Declarar interfaces
Una interfaz parece una clase sin código. Para declarar una interfaz en VB.NET, utilice la palabra clave Interface en lugar de Class.
Función de las interfaces
Las siguientes son dos funciones importantes de las interfaces.
1. Los métodos de la interfaz son públicos implícitamente Los métodos declarados en una interfaz son públicos implícitamente. Por lo tanto, no se permiten los modificadores de acceso públicos explícitos.
2. Los métodos de interfaz no contienen cuerpos de métodos.
Implementar varias interfaces. A pesar de que VB.NET permite únicamente la herencia única, le permite implementar varias interfaces en una clase única.
Implementación de la interfaz. Una clase puede implementar cero o más interfaces, pero puede ampliar explícitamente no más de una clase. Por el contrario, una interfaz puede ampliar cero o más interfaces.
Capacidad de acceso. Una clase puede ser más accesible que sus interfaces base. Por ejemplo, puede declarar una clase pública que implemente una interfaz privada. Sin embargo, una interfaz no puede ser más accesible que cualquiera de sus interfaces base. Es un error declarar una interfaz pública que amplíe una interfaz privada.
Métodos de la interfaz. Una clase debe implementar todos los métodos de cualquier interfaz que amplía, independientemente de si las interfaces se heredan de manera directa o indirecta.
Acceso. El método que la clase implementa debe ser idéntico al del método de la interfaz en todos los sentidos. Debe tener el mismo acceso, debido a que el método de interfaz es público implícitamente, esto significa que el método de implementación se debe declarar público explícitamente. Si se omite el modificador de acceso, entonces el método por predeterminación será privado.
Tipo de devolución. Si el tipo de devolución de la interfaz se declara como T, entonces el tipo de devolución en la clase de implementación no se puede declarar como un tipo derivado de T; debe ser T. En otras palabras, la co-variación del tipo de devolución no está soportada en VB.NET.
Varias clases pueden implementar la misma interfaz. La implementación específica de los miembros de la interfaz pertenece a cada clase implementada.
Comparar las clases abstractas con las interfaces
Tanto las clases abstractas como las interfaces existen para derivarse (o implementarse). Sin embargo, una clase puede emplear a lo sumo una clase abstracta, de manera que debe tener más cuidado al derivar a partir de una clase abstracta que al derivar a partir de una interfaz. Reserve el uso de clases abstractas para implementar relaciones verdaderas “es un”.
Las similitudes entre las clases abstractas y las interfaces son que:
No pueden crear instancias. Esto significa que no se pueden utilizar directamente para crear objetos.
Las diferencias entre las clases abstractas y las interfaces son las siguientes:
Interfaces
- No puede contener implementaciones
- No puede declarar miembros no públicos
- Puede ampliar únicamente otras interfaces
Clases abstractas
- Puede contener implementaciones
- Puede declarar miembros no públicos
- Puede ampliar otras clases, que pueden ser no abstractas
Herencia en Visual Basic .Net
La herencia nos permite crear una nueva clase que automáticamente tenga el comportamiento y métodos de otra existente. De alguna manera es como si estuviéramos fusionando el código de la vieja clase con el de la nueva, pero sin tener que volver a escribirlo (o copy/paste).
Class claseBase
End Class
Class claseHija
Inherits claseBase
End Class
Para indicar que una clase hereda de otra se usa la palabra reservada Inherits.
Una clase puede heredar de una sola clase.
Sobrecarga de Métodos (Overload)
La sobrecarga de métodos nos permite que una clase tenga más de un método con el mismo nombre, siempre y cuando todos los métodos tengan diferentes parámetros. Lo que importa no es el nombre de los parámetros sino su tipo de dato, así como su cantidad. El conjunto de los tipos de dato de los parámetros de un método es lo que se conoce como firma del método (method signature).
Public Sub metodo()
End Sub
Public Sub metodo(ByVal parametro as tipo)
End Sub
Sobrecarga de Métodos en una Subclase
Es obligatorio incluir la palabra Overloads para cualquier método de una subclase que hace una sobrecarga de un método de una clase base.
Public Overloads Sub metodo(ByVal parametro1 as tipo, ByVal parametro2 as tipo)
End Sub
Sobrescritura de métodos
El diseñador de una clase base es responsable de pensar por adelantado los posibles usos que otros desarrolladores puedan darle usando herencia. En particular, el diseñador de una clase debe decidir si un método en particular puede ser alterado, reemplazado o nada de esto.
Si no se especifica lo contrario, los métodos no pueden ser alterados o reemplazados.
Para especificar que un método puede ser alterado o reemplazado utilizando Override debemos marcarlo con el modificador Overridable.
Clase base:
Public Overridable Property Precio() As Single
Get
Return sngPrecio
End Get
Set(ByVal Value As Single)
sngPrecio = Value
End Set
End Property
Clase hija:
Public Overrides Property Precio() As Single
Get
If MultiplesPistas Then
Return MyBase.Precio* 2
Else
Return MyBase.Precio
End If
End Get
Set(ByVal Value As Single)
MyBase.Precio = Value
End Set
End Property
En la sobrescritura debe mantenerse el ámbito de los métodos sobrescritos.
Ejecutando métodos sobrescritos
Cuando usamos herencia podemos elegir declarar nuestra variable como del tipo de la clase base en lugar del objeto real a utilizar. Esto es muy útil ya que podemos escribir código genérico que funcione sin importarnos el tipo real del objeto que estamos manipulando (esta es una de las características de la programación OO que se conoce como Polimorfismo).
Public claseBase variable = new claseHija()
El Polimorfismo es la capacidad de utilizar el mismo código con objetos de diferente tipo, y es algo muy útil.
Puede usarse la función CType(objeto, tipo) para convertir “al vuelo” en tipos compatibles.
Cuando un método es marcado con Overridable se convierte en un método virtual. Esto significa que sin importar el tipo de la variable que usemos siempre se va a ejecutar la implementación que dicta el tipo del objeto.
Para aclarar un poco las cosas veamos que ocurre con las diferentes combinaciones posibles entre tipos de objetos y variables:
| Variable | Objeto | Método Invocado |
| Clase Base | Clase Base | Clase Base |
| Clase Base | Subclase | Subclase |
| Subclase | Subclase | Subclase |
Esto es muy importante ya que podemos estar seguros de que al escribir código genérico como el mostrado más arriba aún se ejecutan los métodos especializados en las subclases, cosa que generalmente es lo deseado.
Sobrescritura con Shadows
Si el método no está marcado con Overridable no nos es posible alterarlo o reemplazarlo. En este caso podemos usar el modificador Shadows para lograr nuestro objetivo reemplazando por completo el método de la clase base.
El uso de Shadows completamente reemplaza al método y todas sus variantes de la clase base, dejando a la subclase con una única versión del método reemplazado (el que acabamos de crear). Usando este modificador no estamos extendiendo una interfaz, sino que estamos reemplazando totalmente un método existente y sus variantes.
Cuando un método es reemplazado con Shadows no es virtual y entonces es el tipo de la variable el que dicta cual implementación del método será invocada. El tipo del objeto que referencia la variable es completamente ignorado.
| Variable | Objeto | Método Invocado |
| Clase Base | Clase Base | Clase Base |
| Clase Base | Subclase | Clase Base |
| Subclase | Subclase | Subclase |
La palabra clave MyBase
Puede utilizar la palabra clave MyBase para llamar a métodos de una clase base cuando reemplace métodos en una clase derivada.
- MyBase hace referencia a la clase base inmediata y a sus miembros heredados. No se puede utilizar para tener acceso a miembros Private de la clase.
- MyBase es una palabra clave, no un objeto real. MyBase no se puede asignar a una variable, pasar a procedimientos ni utilizar en una comparación Is.
- No es necesario definir el método al que califica MyBase en la clase base inmediata; puede definirse en una clase base heredada indirectamente. Para compilar correctamente una referencia calificada mediante MyBase, alguna clase base debe contener un método correspondiente al nombre y el tipo de los parámetros que aparezcan en la llamada.
- No puede utilizar MyBase para llamar a métodos de clase base con el modificador MustOverride.
- No se puede utilizar MyBase para calificarse a sí misma. Por tanto, el siguiente código no es válido:
- MyBase.MyBase.BtnOK_Click() ' Syntax error.
- No se puede utilizar MyBase en módulos.
- No se puede utilizar MyBase para tener acceso a miembros de clase base marcados como Friend si la clase base está en un ensamblado diferente.
La palabra clave MyClass
La palabra clave MyClass permite llamar a un método Overridable implementado en la clase y asegurarse de que se llama a la implementación del método en esta clase y no a la de un método reemplazado en una clase derivada.
- MyClass es una palabra clave, no un objeto real. No se puede asignar a una variable, pasar a procedimientos ni utilizar en una comparación Is.
- MyClass hace referencia a la clase base inmediata y a sus miembros heredados.
- MyClass puede utilizarse como calificador de miembros Shared.
- MyClass no se puede utilizar en módulos estándar.
- MyClass puede utilizarse para calificar un método que está definido en un clase base y que no tiene ninguna implementación del método proporcionado en esa clase. Tal referencia tiene el mismo significado que MyBase.Method.
Impedir herencia
Para impedir que se pueda heredar de una clase debe emplearse el modificador NotInheritable.
Clases en Visual Basic .Net
La definición de una clase consta de campos y métodos. Un campo es una variable de la clase y usualmente es privada. Un método es una propiedad, función o procedimiento dentro de una clase. Es conveniente listar primero los campos, después las propiedades y los métodos constructores, métodos de apoyo y por último el resto de métodos.
Private|Public Class nombreClase
campos
propiedades
constructores
métodos
End Class
Atención es posible crear más de una Clase dentro de un módulo de Clase siempre y cuando las clases se encuentren delimitadas por las instrucciones de inicio (Public Class) y final (End Class) de la Clase.
Campos
Public|Dim|Protected|Private|Friend|Const nombreCampo As tipoCampo
Dim – Variable privada al bloque.
Public – Accesible desde cualquier parte del mismo proyecto, desde otros proyectos que hagan referencia al proyecto, y desde un ensamblado generado a partir del proyecto.
Protected - Accesible desde dentro de la misma clase o desde una clase derivada de ella.
Private - Accesible dentro del mismo módulo, clase o estructura.
Friend - Accesible desde dentro del mismo proyecto, pero no desde fuera de él.
Protected Friend - Accesible desde clases derivadas o desde dentro del mismo proyecto, o ambos.
Const – Constantes, no requieren que se instancie la clase para ser accesibles.
Métodos
Propiedades
Los campos privados de una clase no pueden ser accedidos por código externo, por lo que si es requerido que los campos sean leídos o cambiados, para ello será necesario incluir procedimientos de propiedades (property procedures) en la definición de la clase.
Los procedimientos de propiedades dan el control de clase sobre como los campos son asignados o regresados. El nombre del procedimiento de propiedad es hecho visible al código externo.
El procedimiento de propiedad Get típicamente recupera un campo privado.
El procedimiento de propiedad Set típicamente asigna un nuevo valor al campo privado.
Para que un código externo pueda ver el valor de un campo pero no pueda cambiar|ver su valor es necesario que el campo sea sólo de lectura|escritura, lo cual es posible antecediendo al nombre del procedimiento de propiedad la palabra reservada ReadOnly|WriteOnly, entonces VB.NET podría omitir el bloque Set/End Set|Get/ End Get, porque es innecesario.
[ReadOnly|WriteOnly] property nombrePropiedad as tipoDato
Get
return nombreCampo
End Get
[Set(ByVal valor as tipoDato)
nombreCampo = valor
End Set]
Funciones y subrutinas
Tienen acceso a todos los datos dentro del objeto incluso si son privados.
[Private|Public] Sub nombreMetodo([parámetros])
sentencias
End Sub
[Private|Public] Function nombreMetodo([parámetros]) as tipoDato
Sentencias
Return variable
End Function
Constructores
Un Constructor es un método especial que se ejecuta durante la creación de un objeto. Todos los métodos constructores son procedimientos llamados New. Una clase puede tener cero, uno o más métodos constructores.
Si una clase tiene más de un método constructor lo que distingue un método constructor de otro es el tipo de dato y número de parámetros que lo define.
Sub New([parámetros])
sentencias
End Sub
Clases parciales
Permiten dividir una clase en varios archivos o partes. Basta con definir la misma clase en más de un sitio y asegurarse de incluir la palabra clave Partial.
Partial Public Class NombreClase
End Class
Métodos y campos estáticos
Para declarar métodos o campos estáticos, es decir que no requieren que se instancia la clase para ser accesibles se utiliza la palabra reservada Shared como modificador tras declarar el ámbito.
Public Shared Sub rutina()
End sub
Programación orientada a objetos en VB .Net, conceptos básicos
Un Objeto es una combinación de datos y acciones que pueden ser tratados como unidad.
Una Clase es una estructura de un objeto, un diseño que describe las propiedades (datos) y métodos (acciones) de un objeto.
.Net Soporta las siguientes tres características Encapsulación, Herencia y Polimorfismo.
Con la encapsulación un objeto es solamente referenciado a través de una interfaz formal evitando efectos laterales. Los datos de las clases deberían ser modificados o recuperados sólo a través de procedimientos apropiados, limitando interactuar al objeto con código externo y manteniendo las operaciones internas del objeto invisibles hacia el mundo exterior. Para ello se utilizan los modificadores Private o Protected para evitar que un procedimiento externo ejecute un método de clase o evitar la lectura y modificación de datos en las propiedades y campos.
La Herencia describe la habilidad para crear una nueva clase basada en la existencia de una clase existente, donde esta clase existente recibe el nombre de Clase Base y la nueva clase derivada de la clase base es llamada Clase Derivada. La clase derivada hereda las propiedades, métodos y eventos de la clase base y puede ser personalizada agregando nuevas propiedades y métodos.
El Polimorfismo es la habilidad de los objetos de diferentes clases para responder apropiadamente a nombres u operadores de métodos idénticos, el polimorfismo permite utilizar nombres compartidos y el sistema podría aplicar el código apropiado para un objeto particular.