Principios de Programación Orientada a Objetos

Enviado por Programa Chuletas y clasificado en Psicología y Sociología

Escrito el en catalán con un tamaño de 12,3 KB

Principios POO

Abstracción, Encapsulación y Reutilización

Abstracción: Capacidad para encapsular y aislar la información importante. Enfocar lo esencial. Reducir la complejidad del objeto.

Encapsulación: Ocultar datos y algoritmos de un objeto, mostrando solo las características esenciales. Aumenta el nivel de abstracción. API (Interfaz del programa): Solo permite ver la parte pública.

Reutilización: Acción de volver a usar algo. Aprovechar elementos existentes. No duplicar el trabajo.

Clases, Objetos y Variables

Clase: Idea abstracta. Representa una familia de objetos. Define los atributos y métodos compartidos por los objetos de la misma familia (clase).

Instancia: Objeto concreto de una clase determinada. Pertenece a una familia de objetos (clase). Asigna un valor concreto a cada atributo de la clase. Tipo nombre = new Tipo();

Variables: Son identificadores asociados a un tipo (int, String, Boolean, ...). El tipo de una variable puede ser una clase. Una instancia se guarda en una variable cuyo tipo es la clase asociada.

Atributos: Un atributo es una variable. Su valor se asigna en el método constructor y puede modificarse en otros métodos. Cada instancia asigna un valor diferente al atributo.

Constructor: Crea una nueva instancia (inicializa atributos). Getter: Devuelve el valor de un atributo. Setter: Cambia el valor de un atributo.

Miembros de Clase y Modificadores

Miembro de clase: Atributo o método que pertenece a la clase. En Java se implementa con el modificador static. En atributos: tendrá el mismo valor para todas las instancias. En métodos: puede ser llamado sin instanciar la clase. No se asocia con ninguna instancia particular. Se accede por el nombre de la clase. Ejemplo: System.out, Math.PI

final: Modificador para clases, métodos o atributos. Para atributos, significa que su valor es constante y debe asignarse al declararse. Normalmente se combina con static. this: Hace referencia a “esta instancia”.

Herencia: Ventajas e Inconvenientes

Ventajas de la herencia: Permite especializar la definición de una clase existente. Todos los miembros de la superclase se heredan. Reutilización: Se aprovecha la definición de la superclase, evitando duplicaciones. Flexibilidad: Se pueden definir nuevos miembros en la subclase. Permite agrupar miembros comunes. Si A pertenece a B, entonces A es una subclase de B.

Inconvenientes: Overhead (esfuerzo adicional) en las llamadas a métodos, ya que el método no necesariamente se encuentra en la clase. Aumenta el tiempo de ejecución. Diseño más complicado: se deben encontrar relaciones apropiadas entre las clases. Peligro de definir jerarquías demasiado profundas. Poca flexibilidad una vez definida la jerarquía. Deslocalización del código: difícil saber dónde se hace cada parte.

Visibilidad y Herencia

Visibilidad y herencia: Cada miembro de la superclase se hereda (incluso los privados). Los miembros con visibilidad privada son inaccesibles desde la subclase. Solución: protected.

super: Especifica que el método a ejecutar es el de la superclase. Amplía funcionalidades a una subclase. Usar atributos de una superclase en una subclase.

La Clase Object y Polimorfismo

La clase Object: En Java, la clase Object es la superclase de todas las demás. Si no se pone extends, una clase hereda por defecto de Object. Al crear una instancia de cualquier clase, siempre se ejecuta el constructor de Object.

Polimorfismo: Mecanismo para tratar colecciones de objetos como si fueran del tipo superclase, independientemente de la subclase instanciada. Existe cuando hay herencia o sobrecarga. Un mismo objeto se comporta de diferentes maneras. Basado en dos mecanismos: tipo declarado de una variable ≠ tipo de instancia guardada; sobreescritura de métodos en las subclases. Si enviamos un mensaje a un objeto:

  • El tipo de la instancia se desconoce en tiempo de compilación.
  • La interpretación del mensaje depende de la instancia concreta.

Ventajas: Código más genérico y simple. Ayuda a aumentar el nivel de abstracción. Permite llamar a un método (posiblemente sobreescrito) sin preocuparse del tipo instanciado. Aumenta el nivel de encapsulamiento.

Variables Polimórficas, Sobreescritura y Sobrecarga

Variables polimórficas: Cada variable tiene dos tipos asociados: tipo declarado (especificado al definir la variable); tipo instanciado (tipo de la instancia guardada). No necesariamente coinciden. El tipo instanciado es subclase (directa o no) del tipo declarado. Solo se pueden llamar métodos de la clase del tipo declarado.

Sobreescritura (overriding): Redefinir un método de la superclase en la subclase. Conserva la signatura (comportamiento), pero cambia la implementación. Signatura de un método: identificador, tipo de retorno, lista de argumentos con tipos.

Sobrecarga: Definir múltiples métodos con el mismo nombre pero con parámetros diferentes. Signatura diferente: se tratan como métodos diferentes.

Mensajes polimórficos: ¿Cómo determina qué versión del método ejecutar? Solución: mirar primero la clase del tipo instanciado. Si el método no está definido allí, mirar en la superclase. Subir jerarquías hasta encontrar el método. Garantía: el método está en la clase del tipo declarado. Excepción: constructores.

Consecuencias de la Sobreescritura, Casting e instanceof

Consecuencias sobreescritura: Redefinición de métodos manteniendo parámetros de entrada. Ya no se usa el código de la superclase. La subclase reutiliza la API de la superclase. No se cambia lo que la instancia puede hacer, sino cómo lo hace.

final: Atributos: no se pueden cambiar; Métodos: no se pueden sobreescribir; Clases: no se puede heredar de ellas.

Casting: Sirve para cambiar el tipo declarado de una instancia.

Upcast: Cambiar a un tipo más general (superclase). Tratar igual las instancias. Siempre es posible. Una instancia de la subclase también lo es de la superclase.

Downcast: Cambiar a un tipo más específico (subclase). Llamar a métodos que no están en la clase del tipo declarado. Puede fallar. Una instancia de la superclase no siempre es instancia de la subclase. Cat c1 = new Cat(); Animal a = c1; // automatic upcasting to Animal Cat c2 = (Cat) a; // manual downcasting back to a Cat

instanceof: Permite saber si una instancia pertenece a una clase. Devuelve un valor booleano (true o false). Ayuda a evitar problemas de downcast. Lo resuelve en tiempo de ejecución.

equals: Método de la clase Object. Útil para comprobar si dos instancias son iguales. if (a.equals(b))

Métodos y Clases Abstractas

Método abstracto: Se declara como un método normal (con signatura), pero sin implementación (acaba en ;). Sirve para agrupar comportamientos. La implementación se hace en la subclase. Solución: declarar getArea y getPerimeter como métodos abstractos en la superclase “Shape”. Proporciona la implementación concreta en las subclases. Puede contener atributos y métodos normales o abstractos. Consecuencias métodos abstractos: Sin implementación. No se pueden ejecutar. Su única función es agrupar comportamientos comunes. Deben ser sobreescritos en las subclases. No pueden ser ni final, ni private, ni static. final → No, porque no podríamos sobreescribir el miembro de la subclase. static → No, porque los métodos abstractos funcionan si existe una instancia. private → No, porque sus miembros no son accesibles a las subclases. Puede contener atributos y métodos normales o abstractos. No reutiliza código (implementación). Reutilizará la API (descripción).

Consecuencias clases abstractas: No se pueden crear instancias de una clase abstracta. Si la clase tiene al menos un método abstracto, será abstracta. Una clase abstracta está pensada para que se herede de ella.

Interfaces

Interfaces: Similar a clases puramente abstractas. Puede contener métodos abstractos. No puede contener atributos ni métodos normales. Puede contener constantes (atributos static y final). No es una clase. Todos sus miembros son abstractos, pero no hace falta incluir el identificador “abstract”. Una interfaz no es una clase. Palabra clave “implements”. Mismo efecto que heredar de una clase abstracta. Todos los métodos abstractos de la interfaz se heredan. Para no ser abstractas, la clase debe sobreescribir todos los métodos abstractos. La herencia múltiple de interfaces evita problemas de implementación conflictivos. Una clase puede implementar múltiples interfaces. Lista de interfaces separadas por “,”. Una interfaz puede heredar de múltiples interfaces: public interface A implements B, C, D. Consecuencias interfaz: Útiles cuando no podemos agrupar comportamientos sin herencia múltiple. Promueven la programación genérica. Pensadas para ser implementadas por clases no abstractas. Reutilización de la API, no del código. No evitan la duplicación del código, solo de los comportamientos.

Agregación y Asociación

Generalización/Especialización: Representa la propiedad de herencia. Se puede expresar con el verbo “Es un”. Bidireccional. A generaliza a B si B especializa A.

Agregación: También conocida como composición. Representa objetos compuestos. Se expresa como: Forma parte de/ tiene un. Bidireccional: Un coche tiene un motor. Un motor forma parte de un coche. Un objeto es compuesto si está formado por otros objetos. Describe modelos que se componen de otros objetos. Permite definir objetos en función de otros objetos existentes. de agregación.

Tipos de agregación: Agregación por contenido (agregación fuerte (composition)): El contenedor no puede existir sin las otras partes que lo forman. Agregación por valor (agregación débil (aggregation)): Los componentes pueden existir independientemente del contenedor.

Test de Rumbaugh: 1. ¿La relación se puede expresar por: Forma parte de..., tiene un...? 2. ¿Las relaciones de los contenedores se aplican automáticamente a las partes (Al eliminar el contenedor, eliminamos las partes?)? 3. ¿Los valores de los atributos de los contenedores se propagan a alguna de las partes (Los atributos viven solo dentro del contenedor.)? 4. ¿Existe subordinación de clases (Una clase no puede existir sin la otra)? Si alguna de las preguntas anteriores tiene una respuesta afirmativa, la relación es de agregación.

Cardinalidad: Es el número de instancias de una clase que se relacionan con las instancias de otra clase. Ejemplo: Un profesor da clase a 10 alumnos. Un alumno tiene un único expediente académico. Propiedad: Define los atributos de cada clase. Conviene siempre especificar en ambos sentidos.

Asociación: Relación por defecto. Conexión semántica que no es de otro tipo. Normalmente bidireccional, pero puede ser unidireccional. Define los roles que existen entre los diferentes objetos. Normalmente binaria, pero puede ser unaria o ternaria. También implica que una clase tiene atributos de otra clase.

Entradas relacionadas: