Docsity
Docsity

Prepara tus exámenes
Prepara tus exámenes

Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity


Consigue puntos base para descargar
Consigue puntos base para descargar

Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium


Orientación Universidad
Orientación Universidad


Herencia, Clases Abstractas y Interfaces en POO (C#), Diapositivas de Semántica de Lenguajes de Programación

La herencia permite crear nuevas clases que reutilizan, extienden y modifican el comportamiento de otras clases. Aprenda sobre clases base y derivadas, métodos abstractos y virtuales, clases abstractas y interfaces en C#. Conceptos relacionados: variables de instancia y clase, acceso a miembros de la clase base, evitar derivación adicional y ocultar miembros.

Tipo: Diapositivas

2017/2018

Subido el 14/04/2022

mauricio-baigorria-ibanez
mauricio-baigorria-ibanez 🇵🇪

2

(1)

3 documentos

1 / 10

Toggle sidebar

Esta página no es visible en la vista previa

¡No te pierdas las partes importantes!

bg1
1
FUNDAMENTOS DE SISTEMAS DE INFORMACION (SI393)
Ciclo 2019-02
Conceptos de Programación en C#
Herencia
La herencia, junto con la encapsulación y el polimorfismo, es una de las tres características
principales (o pilares) de la programación orientada a objetos. La herencia permite crear nuevas
clases que reutilizan, extienden y modifican el comportamiento que se define en otras clases.
La clase cuyos miembros se heredan se denomina clase base y la clase que hereda esos
miembros se denomina clase derivada. Una clase derivada solo puede tener una clase base
directa. Sin embargo, la herencia es transitiva. Si ClassC se deriva de ClassB y ClassB se deriva
de ClassA, ClassC hereda los miembros declarados en ClassB y ClassA.
Conceptualmente, una clase derivada es una especialización de la clase base. Por ejemplo, si
tiene una clase base Animal, puede tener una clase derivada denominada Mammal y otra clase
derivada denominada Reptile. Mammal es Animal y Reptile es Animal, pero cada clase
derivada representa especializaciones diferentes de la clase base.
Al definir una clase para derivar de otra clase, la clase derivada obtiene implícitamente todos
los miembros de la clase base, salvo sus constructores y destructores. La clase derivada puede,
por tanto, reutilizar el código de la clase base sin tener que volver a implementarlo. En la clase
derivada, puede agregar más miembros. De esta manera, la clase derivada extiende la
funcionalidad de la clase base.
Métodos abstractos y virtuales
Cuando una clase base declara un método como virtual, una clase derivada puede invalidar el
método con su propia implementación. Si una clase base declara un miembro como abstracto,
ese método se debe sobrescribir en cualquier clase no abstracta que herede directamente de
dicha clase. Si una clase derivada es abstracta en sí misma, hereda los miembros abstractos sin
implementarlos. Los miembros abstractos y virtuales son la base para el polimorfismo, la
segunda característica principal de la programación orientada a objetos.
Clases base abstractas
Puede declarar una clase como abstracta si desea evitar la creación directa de instancias por
medio de la palabra clave new. Si hace esto, la clase solo se puede utilizar si una nueva clase
se deriva de ella. Una clase abstracta puede contener una o más firmas de método que se
declaran a mismas como abstractas. Estas firmas especifican los parámetros y el valor
devuelto pero no tienen ninguna implementación cuerpo del método﴿. Una clase abstracta no
tiene que contener miembros abstractos; sin embargo, si una clase contiene un miembro
abstracto, la propia clase se debe declarar como abstracta. Las clases derivadas que no son
abstractas por sí mismas deben proporcionar la implementación de cualquier método abstracto
de una clase base abstracta.
pf3
pf4
pf5
pf8
pf9
pfa

Vista previa parcial del texto

¡Descarga Herencia, Clases Abstractas y Interfaces en POO (C#) y más Diapositivas en PDF de Semántica de Lenguajes de Programación solo en Docsity!

FUNDAMENTOS DE SISTEMAS DE INFORMACION (SI393)

Ciclo 2019 - 02 Conceptos de Programación en C# Herencia La herencia, junto con la encapsulación y el polimorfismo, es una de las tres características principales (o pilares) de la programación orientada a objetos. La herencia permite crear nuevas clases que reutilizan, extienden y modifican el comportamiento que se define en otras clases. La clase cuyos miembros se heredan se denomina clase base y la clase que hereda esos miembros se denomina clase derivada. Una clase derivada solo puede tener una clase base directa. Sin embargo, la herencia es transitiva. Si ClassC se deriva de ClassB y ClassB se deriva de ClassA, ClassC hereda los miembros declarados en ClassB y ClassA. Conceptualmente, una clase derivada es una especialización de la clase base. Por ejemplo, si tiene una clase base Animal, puede tener una clase derivada denominada Mammal y otra clase derivada denominada Reptile. Mammal es Animal y Reptile es Animal, pero cada clase derivada representa especializaciones diferentes de la clase base. Al definir una clase para derivar de otra clase, la clase derivada obtiene implícitamente todos los miembros de la clase base, salvo sus constructores y destructores. La clase derivada puede, por tanto, reutilizar el código de la clase base sin tener que volver a implementarlo. En la clase derivada, puede agregar más miembros. De esta manera, la clase derivada extiende la funcionalidad de la clase base. Métodos abstractos y virtuales Cuando una clase base declara un método como virtual, una clase derivada puede invalidar el método con su propia implementación. Si una clase base declara un miembro como abstracto, ese método se debe sobrescribir en cualquier clase no abstracta que herede directamente de dicha clase. Si una clase derivada es abstracta en sí misma, hereda los miembros abstractos sin implementarlos. Los miembros abstractos y virtuales son la base para el polimorfismo, la segunda característica principal de la programación orientada a objetos. Clases base abstractas Puede declarar una clase como abstracta si desea evitar la creación directa de instancias por medio de la palabra clave new. Si hace esto, la clase solo se puede utilizar si una nueva clase se deriva de ella. Una clase abstracta puede contener una o más firmas de método que se declaran a sí mismas como abstractas. Estas firmas especifican los parámetros y el valor devuelto pero no tienen ninguna implementación ﴾cuerpo del método﴿. Una clase abstracta no tiene que contener miembros abstractos; sin embargo, si una clase contiene un miembro abstracto, la propia clase se debe declarar como abstracta. Las clases derivadas que no son abstractas por sí mismas deben proporcionar la implementación de cualquier método abstracto de una clase base abstracta.

Interfaces Una interface es un tipo de referencia similar en cierto modo a una clase base abstracta compuesta únicamente por miembros abstractos. Cuando una clase implementa una interfaz, debe proporcionar una implementación para todos los miembros de la interfaz. Una clase puede implementar varias interfaces aunque solo puede derivar de una única clase base directa. Las interfaces se utilizan para definir funciones específicas para las clases que no tienen necesariamente una relación de identidad. Por ejemplo, la interface System.IEquatable puede ser implementada por cualquier clase o struct que deba permitir al código de cliente determinar si dos objetos del tipo son equivalentes ﴾sin embargo, el tipo define la equivalencia﴿. IEquatable no implica el mismo tipo de relación "es un(a)" que existe entre una clase base y una clase derivada (por ejemplo, un Mammal es un Animal). Acceso de la clase derivada a los miembros de la clase base Una clase derivada tiene acceso a los miembros public, protected, internal y protected internal de una clase base. Aunque una clase derivada hereda los miembros privados de una clase base, no puede tener acceso a estos miembros. Sin embargo, todos los miembros privados siguen presentes en la clase derivada y pueden hacer el mismo trabajo que harían en la propia clase base. Por ejemplo, supongamos que un método protegido de la clase base tiene acceso a un campo privado. Este campo debe estar presente en la clase derivada para que el método heredado de la clase base funcione correctamente. Evitar la derivación adicional Una clase puede evitar que otras clases hereden de ella, o de cualquiera de sus miembros, declarándose a sí misma o al miembro como sealed. Ocultar miembros de la clase base en la clase derivada Una clase derivada puede ocultar miembros de la clase base si los declara con el mismo nombre y firma. Se puede utilizar el modificador new para indicar explícitamente que no se pretende que el miembro sea una invalidación del miembro base. No es necesario utilizar new, pero se generará una advertencia del compilador si no se usa new. Clase abstracta e interface Una interface contiene las definiciones de un grupo de funciones relacionadas que una clase o struct pueda implementar. Mediante las interfaces se puede incluir, por ejemplo, un comportamiento de varios orígenes en una clase. Esta capacidad es importante en C# porque el lenguaje no admite la herencia múltiple de clases. Además, debe usar una interfaz si desea simular la herencia de estructuras, porque no pueden heredar de otra estructura o clase. Defina una interface mediante usando palabra clave interface.

Las variables de instancia se utilizan a través de los métodos de la clase y estos son utilizados por objetos. Es decir si tenemos la clase Cuenta, para utilizar la cuenta bancaria, con el constructor vacío Cuenta() y el Constructor(double saldo) con parámetro y definimos algunos objetos como lo siguiente: Cuenta juan, pedro, luis; juan = new Cuenta(); pedro = new Cuenta(1500.0); luis = new Cuenta(3000.0); Al usar la palabra new estamos creando un nuevo objeto de la clase y con esto estamos utilizando una nueva plantilla de variables de instancia para el objeto creado, juan, pedro y luis son objetos nuevos de la clase Cuenta y por cada variable que tiene definida Cuenta en la clase, cada uno de estos objetos podrá tener un valor diferente. IMPORTANTE. Es sumamente importante que después de declarar un objeto para una clase (Cuenta objeto;) hagamos la creación del objeto, es decir utilicemos la instrucción new Cuenta() para ese objeto ( objeto = new Cuenta(); ) de otra manera el objeto no ha sido creado y no se pueden utilizar los métodos. Asociación, Agregación, Composición y Dependencia con C# En la actualidad existe mucho material en Internet que habla sobre asociación, composición, agregación y dependencia pero en la mayoría no se pone énfasis en la implementación de los conceptos sino en el análisis conceptual. La realidad es que la forma de implementar cada tipo de relación es diferente (aunque parezcan mínimas las diferencias) pero es muy importante para un programador conocerlas a la hora de leer un diagrama de clases. Es importante también aclarar que un diagrama de clases realizado por un analista funcional no es un modelo que se debe implementar así directamente, sino que debe ser analizado y comprendido por el programador para producir el verdadero diagrama de clases a implementar. Eso es así debido a que durante el análisis y relevamiento se piensa en "describir" y no en solucionar. Así, el diagrama del analista funcional explica el domino del problema, mientras que el diagrama que realiza el programador explica el dominio de la solución. En este último pueden surgir clases que originalmente no estaban pero son necesarias para realizar una buena implementación (cuestiones de arquitectura, patrones, etc.). Es necesario acostumbrarse al término implementación, el cual se refiere al código de programación concreto de algo. Por ejemplo, si dicen "esta clase es la implementación de aquella " están diciendo "este es el código fuente específico que aplica lo que dice aquella clase abstracta (o interfaz)".

Tanto la asociación, agregación, composición y dependencia son formas de representar las relaciones que existen entre clases. Por ejemplo el siguiente diagrama: La clase Persona tiene una relación de composición con la clase Domicilio. Conceptualmente esto significa que los domicilios son una parte inseparable de la persona, por lo que si no existiera una persona entonces el domicilio de la misma debería desaparecer. Si analizamos más en profundidad encontramos también que, si hubiera que persistir esta relación en una base datos tendríamos una tabla Domicilios cuyo ID sería IdPersona, y una tabla Personas con el mismo ID. El hecho de que la tabla Domicilios no tenga su propio ID sino el de la otra tabla significa que cada registro de la tabla no tiene el peso propio suficiente, que depende 100% de la existencia del mismo ID en la tabla de Personas. Si se llegase a borrar un registro de la tabla Personas habría que borrar su correspondiente registro de la tabla Domicilios para mantener la integridad de la información. Por esta razón también se dice que la relación de composición es una relación fuerte, ya que una instancia arrastra a la otra en caso de eliminación (tanto de objetos en memoria como de registros en base de datos). Ahora, es válido preguntarse ¿por qué razón si es algo inseparable de la persona no lo pongo como un atributo más de la clase persona, por ejemplo de tipo string y no me complico tanto? Efectivamente la clase Domicilio es un atributo de la clase Persona, y justamente la línea que las conecta es lo que indica la presencia del atributo. Domicilio existe como clase aparte porque en realidad no es un simple string sino un conjunto de atributos, por ejemplo: calle, numeración, piso, departamento, distrito, etc. Todos esos atributos forman parte de una entidad, el Domicilio, y no sería correcto dejarlos sueltos dentro de la clase Persona. Por eso también se persisten en tablas separadas si fuera necesario.

IdSucursal, la cual permite la navegación en dos direcciones sin invadir a ninguna de las tablas reales. El caso especial se presenta cuando en una asociación es necesario reflejar atributos de información. Por ejemplo, es necesario registrar la fecha de inicio y la fecha de fin de la vinculación entre empleados y sucursales. Desde el punto de vista de la persistencia no es una complicación ya que la tabla intermedia que vincula a Personas y Sucursales tendrá más campos de información. Pero desde el punto de vistas de entidades hay un cambio más importante: es necesario crear una nueva entidad. Si un vínculo necesita guardar información deja de ser un vínculo y pasa a ser una entidad nueva, con derecho a tener su propio nombre (no simplemente la unión de los nombres Persona y Sucursal) porque en el paradigma orientado a objetos todo lo que tenga atributos (características) debe ser una entidad. Sin embargo en el modelo de persistencia la tabla intermedia sí suele tener por nombre simplemente la unión de las dos tablas. Lo que tiene de particular esta entidad es que solo tiene sentido si existen las dos partes, con lo cual en el modelo de persistencia no debe tener clave primaria a menos que esto no sea cierto y la información del vínculo deba persistir más allá de la existencia de las partes que participaron (si así lo dice el negocio...). En este supuesto sí correspondería agregarle una clave primaria a la tabla intermedia. La implementación de esta entidad intermedia puede resolverse con una clase "TiempoEnSucursal" (disculpen por el nombre, importa ver que tiene nombre propio), la cual no tendrá un identificador propio, pero tendrá una propiedad de tipo Sucursal y otra de tipo Persona (además de la fecha de inicio y fecha de fin propias de la clase). Por último, estas propiedades de Sucursal y Persona deberían provenir desde afuera de la clase PasoPorSucursal, es decir, por medio de algún constructor o en el "set" de las propiedades.

Para finalizar les dejo la implementación de las clases donde se puede ver en detalle cómo se aplican los tres tipos de relaciones.

 Una clase no abstracta derivada de una clase abstracta debe incluir implementaciones reales de todos los descriptores de acceso y métodos abstractos heredados. Utilice el modificador abstract en una declaración de método o propiedad para indicar que el método o la propiedad no contienen implementación. Los métodos abstractos presentan las siguientes características:  Un método abstracto es, implícitamente, un método virtual.  Las declaraciones de métodos abstractos sólo se permiten en clases abstractas.  Debido a que una declaración de método abstracto no proporciona una implementación, no existe cuerpo del método; la declaración de método finaliza simplemente con un punto y coma y sin llaves ({ }) después de la firma. La implementación la proporciona un método de reemplazo override, que es miembro de una clase no abstracta.  Utilizar los modificadores static o virtual en una declaración de método abstracto produce un error.