CodeGym /Blog Java /Random-ES /Principios de programación orientada a objetos
Autor
Jesse Haniel
Lead Software Architect at Tribunal de Justiça da Paraíba

Principios de programación orientada a objetos

Publicado en el grupo Random-ES
¡Hola! En la lección de hoy, hablaremos sobre los principios de la programación orientada a objetos. ¿Alguna vez te has preguntado por qué Java está diseñado exactamente como es? Quiero decir, declaras clases y creas objetos basados ​​en clases, las clases tienen métodos, etc. Pero, ¿por qué el lenguaje está estructurado para que los programas consistan en clases y objetos, y no en otra cosa? ¿Por qué se inventó y puso en primer plano el concepto de "objeto"? ¿Todos los lenguajes están diseñados de esta manera? Si no, ¿qué ventajas le da a Java? Como puede ver, hay muchas preguntas :) Intentemos responder cada una de ellas en la lección de hoy.

¿Qué es la programación orientada a objetos (POO)?

Por supuesto, Java no se compone de objetos y clases solo por diversión. No son un capricho de los creadores de Java, ni siquiera su invención. Hay muchos otros lenguajes basados ​​en objetos. El primer lenguaje de este tipo se llamó "Simula". Fue inventado en la década de 1960 en Noruega. Además, los conceptos de "clase" y "método" aparecieron en Simula. Según los estándares del desarrollo de software, "Simula" parece un lenguaje antiguo, pero cualquiera puede ver su "parecido familiar" con Java. Principios de la programación orientada a objetos - 1Probablemente puedas leer fácilmente el código escrito en este lenguaje y explicar a grandes rasgos lo que hace :)

Begin
	Class Rectangle (Width, Height); Real Width, Height;
			           
	 Begin
	    Real Area, Perimeter;  
	 
	    Procedure Update;      
	    Begin
	      Area := Width * Height;
              OutText("Rectangle is updating, Area = "); OutFix(Area,2,8); OutImage;
	      Perimeter := 2*(Width + Height);
              OutText("Rectangle is updating, Perimeter = "); OutFix(Perimeter,2,8); OutImage;
	    End of Update;
	 
	    Update;               
	    OutText("Rectangle created: "); OutFix(Width,2,6);
	    OutFix(Height,2,6); OutImage;
	 End of Rectangle;

       Rectangle Class ColouredRectangle (Color); Text Color;
			           
	Begin   	  
	    OutText("ColouredRectangle created, color = "); OutText(Color);
	    OutImage;
        End of ColouredRectangle;

 
      	 Ref(Rectangle) Cr;            
	 Cr :- New ColouredRectangle(10, 20, "Green"); 
End;
Este código de ejemplo de código fue tomado de "Simula - 50 años de programación orientada a objetos" por Weekly-geekly. Como puedes ver, Java no es muy diferente de su abuelo :) Esto se debe a que la aparición de Simula marcó el nacimiento de un nuevo concepto: la programación orientada a objetos. Wikipedia define OOP así: "La Programación Orientada a Objetos (OOP) es un paradigma de programación basado en el concepto de "objetos", que pueden contener datos, en forma de campos (a menudo conocidos como atributos), y código, en forma de procedimientos (a menudo conocidos como métodos)". En mi opinión, esta es una muy buena definición. No hace mucho que empezaste a aprender Java, pero esta definición probablemente no contenga palabras que no conozcas :) Hoy en día, OOP es la metodología de programación más común. Además de Java, Los principios de programación orientada a objetos se utilizan en muchos lenguajes populares de los que quizás haya oído hablar. Por ejemplo, C++ (utilizado activamente en el desarrollo de juegos), Objective-C y Swift (utilizado para escribir programas para dispositivos Apple), Python (el más popular en aprendizaje automático), PHP (uno de los lenguajes de desarrollo web más populares), JavaScript ( es más fácil decir para qué no se usa) y muchos otros. Entonces, ¿cuáles son los principios de OOP de todos modos? Te lo contamos en detalle. ¿Cuáles son los principios de OOP de todos modos? Te lo contamos en detalle. ¿Cuáles son los principios de OOP de todos modos? Te lo contamos en detalle.

Principios de programación orientada a objetos

Estos son los cimientos de los cimientos. Las 4 características principales que juntas forman el paradigma de la programación orientada a objetos. Comprenderlos es esencial para convertirse en un programador exitoso.

Principio 1. Herencia

Buenas noticias: ¡ya conoces algunos de los principios de la programación orientada a objetos! :) Ya nos hemos encontrado con la herencia un par de veces en las lecciones, y logramos usarla. La herencia es un mecanismo que le permite describir una nueva clase basada en una clase existente (principal). Al hacerlo, la nueva clase toma prestadas las propiedades y la funcionalidad de la clase principal. ¿Para qué sirve la herencia y qué ventajas aporta? Sobre todo, la reutilización de código. Los campos y métodos declarados en las clases principales se pueden usar en las clases descendientes. Si todos los tipos de automóviles tienen 10 campos comunes y 5 métodos idénticos, solo necesita moverlos a Autoclase de padres. Puedes usarlos en clases descendientes sin ningún problema. Sólidas ventajas: tanto cuantitativas (menos código) como, en consecuencia, cualitativas (las clases se vuelven mucho más simples). Además, la herencia es muy flexible: puede agregar funciones de escritura separadas que faltan en los descendientes (algunos campos o comportamientos que son específicos de una clase en particular). En general, como en la vida real, todos somos algo parecidos a nuestros padres, pero también algo diferentes a ellos :)

Principio 2. Abstracción

Este es un principio muy simple. Abstracción significa identificar las características principales y más significativas de algo, y al mismo tiempo descartar cualquier cosa menor e insignificante. No hay necesidad de reinventar la rueda. Recordemos un ejemplo de una vieja lección sobre clases. Supongamos que estamos creando un sistema de archivo para los empleados de la empresa. Para crear objetos de "empleado", hemos escrito una clase de empleado . ¿Qué características son importantes para describirlas en el sistema de archivo de la empresa? Nombre, fecha de nacimiento, SSN e identificación de empleado. Pero es poco probable que necesitemos la altura, el color de ojos o el color de cabello del empleado para este tipo de registro. La empresa no tiene necesidad de tal información sobre un empleado. Entonces, en la clase Empleado , declaramos las siguientes variables:, int edad , int socialSecurityNumber e int employeeId . Y abstraemos información innecesaria como el color de los ojos. Sin embargo, si estamos creando un sistema de archivo para una agencia de modelos, la situación cambia drásticamente. La altura, el color de los ojos y el color del cabello de una modelo son características importantes, pero su SSN es absolutamente irrelevante para nosotros. Entonces, en la clase Model , creamos las siguientes variables: String height , String hair , String eyes .

Principio 3. Encapsulación

Ya nos hemos topado con esto. En Java, la encapsulación significa restringir la capacidad de leer y cambiar datos. Como puede ver, el término se basa en la palabra "cápsula". Usaremos una "cápsula" para ocultar algunos datos importantes que no queremos que otros cambien. He aquí un ejemplo simple de la vida real. Tienes un nombre y un apellido. Todos tus amigos los conocen. Pero no tienen la capacidad de cambiar su nombre o apellido. Podríamos decir que el proceso para hacer eso está "encapsulado" por el sistema judicial: puede cambiar su apellido solo a través del secretario de la corte, y solo usted puede hacerlo. Otros "usuarios" tienen acceso de "solo lectura" a su nombre y apellido :) Otro ejemplo ilustrativo es el efectivo guardado en casa. Dejarlo a la vista en medio de tu habitación no es una buena idea. Cualquier "usuario" (persona que viene a tu casa) podrá cambiar el monto de tu dinero, es decir, podrá tomar tu dinero. Sería mejor encapsularlo en una caja fuerte. Entonces el acceso estaría disponible solo para usted y solo mediante el uso de un código especial. Ejemplos obvios de encapsulación con los que ya ha trabajado son los modificadores de acceso (privado, público, etc.), así como los setters y getters. Si no encapsula elcampo de edad de la clase Cat , entonces cualquiera puede escribir:

Cat.age = -1000;
El mecanismo de encapsulación nos permite proteger el campo de edad con un método de establecimiento, donde podemos asegurarnos de que la edad no se pueda establecer en un número negativo.

Principio 4. Polimorfismo

El polimorfismo es la capacidad de trabajar con varios tipos como si fueran del mismo tipo. Además, el comportamiento de los objetos será diferente dependiendo de su tipo. ¿Suena complicado? Vamos a darle sentido ahora mismo. Tomemos el ejemplo más simple: los animales. Cree una clase Animal con un solo método speak() y dos subclases: Cat y Dog .

public class Animal {

   public void speak() {
      
       System.out.println("Hello!");
   }
}

public class Dog extends Animal {
  
   @Override
   public void speak() {
       System.out.println ("Woof-woof!");
   }
}

public class Cat extends Animal {

   @Override
   public void speak() {
       System.out.println("Meow!");
   }
}
Ahora intentaremos declarar una variable de referencia Animal y asignarle un objeto Perro .

public class Main {

   public static void main(String[] args) {

       Animal dog = new Dog();
       dog.speak();
   }
}
¿Qué método crees que se llamará? Animal.speak() o Dog.speak() ? El método en la clase Dog se llamará: ¡Guau, guau! Creamos una referencia Animal , pero el objeto se comporta como un Perro . Si es necesario, podría comportarse como un gato, un caballo o algún otro animal. Lo importante es asignar una subclase específica a la variable de referencia general Animal . Esto tiene sentido, porque todos los perros son animales. Eso es lo que teníamos en mente cuando dijimos "el comportamiento de los objetos será diferente dependiendo de su tipo". Si creamos un objeto Gato ...

public static void main(String[] args) {

   Animal cat = new Cat();
   cat.speak();
}
el método speak() mostraría "¡Miau!" Pero, ¿qué entendemos por 'la capacidad de trabajar con varios tipos como si fueran del mismo tipo'? Esto también es bastante sencillo. Imaginemos que estamos creando una barbería para animales. Nuestra barbería debería poder recortar cualquier animal, por lo que creamos un método trim() con un parámetro Animal (el animal al que se corta el pelo).

public class AnimalBarbershop {

   public void trim(Animal animal) {

       System.out.println("The haircut is done!"); 
   }
}
¡ Y ahora podemos pasar objetos Gato y Perro al método trim() !

public static void main(String[] args) {

   Cat cat = new Cat();
   Dog dog = new Dog();

   AnimalBarbershop barbershop = new AnimalBarbershop();

   barbershop.trim(cat);
   barbershop.trim(dog);
}
Y aquí está el claro ejemplo: la clase AnimalBarbershop trabaja con los tipos Gato y Perro como si fueran del mismo tipo. Al mismo tiempo, Gato y Perro tienen comportamientos diferentes: cada uno habla de manera diferente.

¿Por qué necesitamos POO?

¿Por qué surgió OOP como un nuevo concepto de programación? Los programadores tenían herramientas funcionales, como lenguajes de procedimiento. ¿Qué los impulsó a inventar algo fundamentalmente nuevo? Sobre todo, la complejidad de las tareas a las que se enfrentaban. Si hace 60 años la tarea del programador era algo así como "evaluar alguna expresión matemática", ahora podría ser algo así como "implementar 7 finales diferentes para el juego STALKER, dependiendo de combinaciones de decisiones del jugador tomadas en los puntos A, B, C, DE , y F en el juego". Como puede ver, las tareas obviamente se han vuelto más complicadas en las últimas décadas. Y como resultado, los tipos de datos se han vuelto más complicados. Esta es otra razón por la que apareció OOP. Una expresión matemática se puede evaluar fácilmente usando primitivas ordinarias. No se necesitan objetos aquí. Pero la tarea con los finales del juego sería difícil incluso de describir sin usar clases personalizadas. Dicho esto, es bastante fácil describirlo usando clases y objetos. Obviamente, necesitaremos varias clases: Game, Stalker, Ending, PlayerDecision, GameEvent, etc. En otras palabras, incluso sin comenzar a resolver el problema, podemos "esbozar" fácilmente una solución en nuestra cabeza. La creciente complejidad de las tareas obligó a los programadores a dividirlas en partes. Pero esto no era tan fácil de hacer en la programación procedimental. Y muy a menudo, un programa era como un árbol con muchas ramas que representaban todas las posibles rutas de ejecución. Dependiendo de ciertas condiciones, se ejecutaba una rama u otra del programa. Para programas pequeños, esto era conveniente, pero era muy difícil dividir un problema grande en partes. Esta fue otra razón más para el surgimiento de OOP. Este paradigma dio a los programadores la capacidad de dividir un programa en un grupo de "módulos" (clases), cada uno de los cuales hace su propia parte del trabajo. Al interactuar entre sí, todos los objetos realizan el trabajo de nuestro programa. Además, podemos reutilizar nuestro código en otras partes del programa, lo que también ahorra mucho tiempo.
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION