JavaRush /Blog Java /Random-ES /Conceptos de programación orientada a objetos JAVA
shabnahm
Nivel 18

Conceptos de programación orientada a objetos JAVA

Publicado en el grupo Random-ES
JAVA se basa en los conceptos de programación orientada a objetos, lo que permite pasar a un nivel superior de abstracción para resolver cualquier problema de forma realista. El enfoque orientado a objetos conceptualiza la solución a un problema en términos de objetos del mundo real que son más fáciles de reutilizar en una aplicación. Por ejemplo, Chair(silla), Fan(ventilador), Dog(perro), Computer(computadora), etc. En JAVA, una clase es un diseño, plantilla o prototipo que define el comportamiento general de un objeto de un tipo determinado. Una instancia es una implementación separada de una clase y todas las instancias de una clase tienen las mismas propiedades, que se describen en la definición de clase. Por ejemplo, puede definir una clase denominada Casa con el número de habitaciones como atributo y crear instancias de la clase, como una casa de dos habitaciones, una casa de tres habitaciones, etc. Conceptos de programación orientada a objetos JAVA - 1Ventajas: A continuación se enumeran algunas ventajas del desarrollo de software orientado a objetos.
  • Reducción de costes de soporte de software, debido principalmente a que se realiza de forma modular.
  • Reutilización de código mejorada a través de características como la herencia, lo que resulta en un desarrollo de software más rápido.
  • Mayor confiabilidad y flexibilidad del código.
  • Facilidad de comprensión debido a la simulación del mundo real.
  • Mejor abstracción a nivel de objeto.
  • Reducir la complejidad de la transición de una fase de desarrollo a otra.
Hay cuatro características principales de la programación orientada a objetos:
  • Encapsulación
  • Herencia
  • Polimorfismo
  • Abstracción

Encapsulación

La encapsulación actúa como un contrato para un objeto sobre lo que debe ocultar y lo que debe abrir para que otros objetos accedan. En JAVA, utilizamos un modificador de acceso privatepara ocultar un método y restringir el acceso a una variable desde el mundo exterior. JAVA también tiene varios modificadores de acceso: public, default, protected, private, que se utilizan para restringir la visibilidad en diferentes niveles. Pero el objetivo final es resumir aquellas cosas que no deberían cambiarse. El enfoque que funciona mejor es que una clase solo debe tener una razón para cambiar, y la encapsulación hace realidad el diseño de esa “única razón”. El enfoque correcto para la encapsulación es ocultar las cosas que cambian con frecuencia para evitar dañar otras clases. Beneficios: A continuación se detallan algunos de los beneficios de la encapsulación:
  • Podemos proteger el estado interno de un objeto ocultando sus atributos.
  • Esto mejora la modularidad del código porque evita que los objetos interactúen de forma inesperada.
  • Mejora la usabilidad del código.
  • Esto respalda la relación contractual de una entidad específica.
  • La encapsulación hace que el software sea más fácil de mantener.
  • Los cambios en el código se pueden realizar de forma independiente.

Polimorfismo

El polimorfismo en programación es la capacidad de proporcionar la misma interfaz para diferentes formas subyacentes (tipos de datos). Esto significa que las clases que tienen diferentes funcionalidades comparten la misma interfaz y pueden llamarse dinámicamente pasando parámetros por referencia. Un ejemplo clásico es la clase Shape(forma) y todas las clases que heredan de ella: square(cuadrado), circle(círculo), dodecahedron(dodecaedro), irregular polygon(polígono irregular), splat(blob), etc. En este ejemplo, cada clase tendrá su propio método Draw()y el código del cliente puede simplemente hacer:
Shape shape = new Shape();
Shape.area()para obtener el comportamiento correcto de cualquier forma La belleza del polimorfismo es que el código, al trabajar con diferentes clases, no necesita saber qué clase está utilizando, ya que todas funcionan según el mismo principio. El proceso utilizado por los lenguajes de programación orientados a objetos para implementar el polimorfismo dinámico se denomina enlace dinámico. Nota: El polimorfismo es la capacidad de elegir métodos más específicos para ejecutar según el objeto. El polimorfismo ocurre cuando no participan clases abstractas. Ventajas:
  • Creando código reutilizable. Es decir, una vez que se crea, implementa y prueba una clase, se puede usar libremente sin preocuparse por lo que está escrito exactamente en ella.
  • Esto permite un código más genérico y poco acoplado.
  • Se reduce el tiempo de compilación, lo que acelera el desarrollo.
  • Vinculación dinámica.
  • Se puede utilizar la misma interfaz para crear métodos con diferentes implementaciones.
  • Toda la implementación se puede reemplazar utilizando las mismas firmas de métodos.
Anulación de método como parte del polimorfismo. Una anulación interactúa con dos métodos: un método de la clase principal y un método de la clase derivada. Estos métodos tienen el mismo nombre y firmas. La anulación le permite realizar la misma operación de diferentes maneras para diferentes tipos de objetos. Por ejemplo:
while(it.hasNext()) {
Shape s = (Shape) it.next();
totalArea += s.area(dim); //будет применен полиморфизм и вызван нужный метод для каждого un objetoа.
}
Conceptos de programación orientada a objetos JAVA - 2Sobrecarga de métodos o polimorfismo ad hoc o polimorfismo estático La sobrecarga interactúa con múltiples métodos de la misma clase que tienen nombres idénticos pero tienen firmas de métodos diferentes. La recarga le permite describir la misma operación de diferentes maneras para diferentes datos. A veces se le llama polimorfismo estático, pero en realidad no es polimorfismo. Esto no es más que simplemente tener dos métodos con los mismos nombres, pero con una lista diferente de argumentos. El reinicio no tiene nada que ver con la herencia y el polimorfismo. Y un método sobrecargado no es en absoluto lo mismo que un método anulado. Polimorfismo paramétrico mediante generación en JAVA Al declarar una clase, el campo de nombre se puede asociar con diferentes tipos y el nombre del método se puede asociar con diferentes parámetros y tipos de retorno. JAVA admite el polimorfismo paramétrico mediante el uso de genéricos.
List<String> list = new ArrayList<String>();
¿Por qué no podemos anular un método estático en JAVA? La anulación depende de la existencia de una instancia de la clase. La idea del polimorfismo es que puedes crear una subclase y los objetos implementados por esas subclases se comportarán de manera diferente con los mismos métodos de la clase principal (anulados en las subclases). Un método estático no está asociado con ninguna instancia de la clase, por lo que no se puede aplicar el concepto de anulación de sí mismo. Los creadores de JAVA se guiaron por dos consideraciones que influyeron en este enfoque. Primero, hay problemas de ejecución de código: hubo muchas críticas a Smalltalk por ser lento (la recolección de basura y el polimorfismo eran parte de este problema), y JAVA fue diseñado para evitar esto. La segunda consideración fue la decisión de que el público objetivo de JAVA serían los desarrolladores de C++. Hacer que los métodos estáticos funcionaran de esta manera era muy familiar para los programadores de C++ y también aceleró las cosas ya que no había necesidad de subir en la jerarquía de clases para determinar a qué método llamar. Vas directamente a la clase y llamas a un método específico.

Herencia

La herencia es el acto de incorporar el comportamiento (es decir, métodos) y el estado (es decir, variables) de una clase base en una clase derivada para que estén disponibles en esa clase derivada. La principal ventaja de la herencia es que proporciona un mecanismo formal para la reutilización del código y evita la duplicación. Una clase heredada amplía la funcionalidad de la aplicación copiando el comportamiento de la clase principal y agregando nueva funcionalidad. Esto hace que el código esté altamente acoplado. Si quieres cambiar la superclase, tendrás que conocer todos los detalles de las subclases para no romper el código. La herencia es una forma de reutilización de software donde se crea una nueva clase (subclase) a partir de una clase existente (superclase) que amplía su funcionalidad y utiliza algunas de las propiedades de la superclase. Entonces, si tienes una clase padre y luego aparece una clase hija, el niño hereda todas las cosas que tiene el padre. Ventajas:
  • Reutilización de código mejorada.
  • Se establece la relación lógica “es un” (es alguien, algo). Por ejemplo: El perro es un animal . (Un perro es un animal).
  • Modularización de código.
  • Se excluyen las repeticiones.
Defecto:
  • Estrechamente acoplado: una subclase depende de la implementación de una clase principal, lo que hace que el código esté estrechamente acoplado.

Abstracción

La abstracción significa diseñar clases en función de sus interfaces y funcionalidades, sin tener en cuenta los detalles de implementación. Una clase abstracta representa interfaces sin incluir la implementación real. Distingue la implementación de un objeto de su comportamiento. La abstracción simplifica el código al ocultar detalles sin importancia. Ventajas:
  • Al utilizar la abstracción, podemos separar lo que se puede agrupar en algún tipo.
  • Las propiedades y métodos que se modifican con frecuencia se pueden agrupar en un tipo separado, por lo que el tipo principal no estará sujeto a cambios. Esto refuerza el principio de programación orientada a objetos: "El código debe estar abierto a la extensión, pero cerrado al cambio " .
  • La abstracción simplifica la representación de modelos de dominio.
Diferencia entre abstracción y encapsulación La encapsulación es una estrategia utilizada como parte de la abstracción. La encapsulación se refiere a la estructura de un objeto: los objetos encapsulan sus propiedades y las ocultan del acceso externo. Los usuarios de una clase interactúan con ella utilizando sus métodos, pero no tienen acceso directo a la estructura de la clase. De esta manera, la clase abstrae los detalles de implementación relacionados con su diseño. La abstracción es un término más general. Esto también se puede conseguir, entre otras cosas, utilizando subclases. Por ejemplo, una clase List(lista) en la biblioteca estándar es una abstracción de una secuencia de elementos, indexados según su lugar en la lista. Ejemplos específicos de una lista Listson ArrayListo LinkedList. El código que interactúa con una lista Listabstrae los detalles de qué lista utiliza. A menudo, la abstracción no es posible sin ocultar el estado subyacente mediante la encapsulación. Si una clase expone su estructura interna, no puede cambiar sus operaciones internas y, por lo tanto, no puede abstraerse. ¿Qué son la clase abstracta y el método abstracto? Sucede que durante el desarrollo desea que una clase base solo proporcione una interfaz para sus clases derivadas. Es decir, no desea que nadie cree instancias de la clase base. Debe utilizar la interfaz de tal manera que solo le envíe objetos (esta es una conversión implícita que permite el comportamiento polimórfico). Esto se logra haciendo que esta clase sea abstracta usando la palabra clave abstract. Esto impone algunas restricciones, como la imposibilidad de crear instancias de una clase abstracta; cuando se utiliza una clase abstracta, es necesario implementar métodos abstractos. Esto asegura el polimorfismo. Una clase abstracta puede contener métodos tanto abstractos como concretos. Si al menos un método de una clase se declara abstracto, toda la clase también debe declararse abstracta. Sin embargo, no es necesario observar la regla en sentido contrario. Si una clase se declara abstracta, no puede contener métodos abstractos. Un método que simplemente define sus firmas y no proporciona una implementación se llama abstracto. Su implementación real se deja en manos de sus subclases, que amplían la clase abstracta. Un objeto no puede utilizar un método abstracto, sólo otra clase puede ampliarlo. ¿Cuándo debería utilizar una clase abstracta? Las clases abstractas le permiten definir algún comportamiento predeterminado y hacer que las subclases proporcionen cualquier comportamiento específico. Por ejemplo: List(lista) es una interfaz, a su vez AbstractListdefine el comportamiento básico de una Lista, que puede usarse tal cual o refinarse en una subclase, por ejemplo, en ArrayList(matriz de lista). ¿Qué es una interfaz? El concepto de interfaz es una clase abstracta, pero la interfaz (definida por la palabra clave interface) va un paso más allá. Impide cualquier implementación de un método o función. Sólo puedes declarar un método o función, pero no proporcionar su implementación. La clase que implementa la interfaz debe encargarse de la implementación real. Las interfaces son muy útiles y se utilizan ampliamente en programación orientada a objetos. Dado que comparten la interfaz en sí y la implementación, ofrecen muchas ventajas de su uso:
  1. Herencia múltiple .
  2. Bajo acoplamiento . Hay una abstracción de la operación, como la estratificación, y la implementación concreta puede ser cualquier cosa: JDBC, JPA, JTA, etc.
  3. El programa de interfaz no está implementado .
  4. Polimorfismo de enlace dinámico : la interfaz de programación de un objeto se expone sin revelar su implementación real.
  5. Niveles abstractos , separación de funcionalidades.
Diferencia entre interfaz y clase abstracta.
  • Una interfaz es una relación contractual con las clases que implementan esta interfaz, estableciendo que la implementación ocurre en la forma designada por la interfaz. Este es un shell vacío con métodos declarados.
  • Una clase abstracta define algún comportamiento general y pide a sus subclases que definan un comportamiento atípico o específico para su clase.
  • Los métodos y miembros de una clase abstracta se pueden designar con cualquier modificador de acceso; a su vez, todos los métodos de la interfaz deben ser públicos.
  • Al heredar una clase abstracta, la clase descendiente debe definir métodos abstractos, mientras que una interfaz puede heredar otra interfaz sin necesariamente definir sus métodos.
  • Una clase descendiente puede extender sólo una clase abstracta, pero una interfaz puede extender o una clase puede implementar muchas otras interfaces.
  • Una clase descendiente puede definir métodos abstractos con el mismo modificador de acceso o menos restrictivo, pero la clase que implementa la interfaz debe definir métodos con el mismo nivel de visibilidad.
  • Una interfaz no contiene constructores, mientras que una clase abstracta sí.
  • Las variables declaradas en la interfaz Java son finales por defecto. Una clase abstracta puede contener variables que no son definitivas.
  • Todos los miembros de la interfaz Java son public. Los miembros de una clase abstracta pueden permitirse el lujo de serlo public, protectedetc.

Composición

La reutilización del código se puede lograr mediante herencia y composición. Pero el uso de la composición proporciona un mayor nivel de encapsulación que la herencia, ya que los cambios en la clase de back-end no necesariamente afectarán el código que pertenece a la clase de front-end. La composición es una técnica de diseño que utiliza relaciones "tiene-a" (tiene, incluye) en las clases. Tanto la herencia de Java como la composición de objetos se pueden utilizar para reutilizar el código. La esencia de la composición es expresar la relación "tiene un" entre objetos. Piensa en una silla. La silla tiene un asiento. La silla tiene respaldo. Una silla tiene un número determinado de patas. La frase "tiene un" sugiere una relación en la que la silla tiene, o al menos utiliza, otro objeto. Ésta es precisamente la relación “tiene-a”, que es la base de la composición. Ventajas:
  • Control de visibilidad
  • La implementación se puede reemplazar en tiempo de ejecución.
  • Acoplamiento flojo, ya que la clase de interfaz no depende de la implementación.
Diferencias entre composición y herencia
No. Composición (tiene un / tiene) Herencia (es un/es)
1 Admite polimorfismo y reutilización de código. Admite polimorfismo y reutilización de código.
2 El objeto de tiempo de ejecución ya ha sido creado. El objeto se crea dinámicamente en tiempo de compilación.
3 La implementación se puede reemplazar en tiempo de ejecución. La implementación se puede cambiar en tiempo de compilación.
4 Una subclase es independiente de su clase padre, lo que favorece el acoplamiento flexible (especialmente bajo control de interfaz). La subclase depende de la implementación de la clase principal, por lo que el enlace se considera fuerte.
5 Uso: La Casa dispone de Baño. Está mal decir que la Casa es el Baño. La herencia es unidireccional: una Casa es un Edificio. Pero el edificio no es una casa.
Nota: No utilice la herencia solo para garantizar la reutilización del código. Si no existe la relación “es un” (es), se utiliza la composición para estos fines. La diferencia entre composición y agregación está en las relaciones de objeto. La agregación es una relación en la que una clase encaja en una colección. Es parte de una relación total, donde una parte puede existir sin el todo. Este tipo de relaciones son mucho más débiles. No hay dependencia cíclica. Por ejemplo: pedido y producto. La composición es una relación en la que una clase encaja en una colección. Es parte de una relación total en la que la parte no puede existir sin el todo. Si se destruye el todo, también se destruirán todos sus componentes. Es una relación más fuerte. Por ejemplo: un polígono y sus vértices, un orden y su componente.
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION