JavaRush /Blog Java /Random-ES /Principios de programación orientada a objetos

Principios de programación orientada a objetos

Publicado en el grupo Random-ES
¡Hola! ¿Alguna vez te has preguntado por qué Java está diseñado como está? En el sentido de que creas clases, basadas en ellas: objetos, las clases tienen métodos, etc. Pero ¿por qué la estructura del lenguaje es tal que los programas constan de clases y objetos, y no de otra cosa? ¿Por qué se inventó y se puso en primer plano el concepto de “objeto”? ¿Todos los lenguajes funcionan de esta manera y, en caso contrario, qué beneficios le aporta a Java? Como puede ver, hay muchas preguntas :) Intentemos responder a cada una de ellas en la conferencia de hoy.

Principios de programación orientada a objetos:

  1. Herencia
  2. Abstracción
  3. Encapsulación
  4. Polimorfismo

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

Por supuesto, Java se compone de objetos y clases por una razón. Esto no es un capricho de sus creadores, ni siquiera de su invención. Hay muchos otros lenguajes que se basan en objetos. El primer lenguaje de este tipo se llamó Simula y se inventó en la década de 1960 en Noruega. Simula introdujo, entre otras cosas, los conceptos de " clase " y " método ". Principios de la programación orientada a objetos - 2
Kristen Nygaard y Ole Johan Dahl - creadores de Simula
Parecería que Simula es un lenguaje antiguo según los estándares de programación, pero su conexión "familiar" con Java es visible a simple vista. Lo más probable es que puedas leer fácilmente el código escrito en él y explicar en términos generales 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;
El ejemplo de código está tomado del artículo Simula: 50 años de programación orientada a objetos . Como puede ver, Java y su antepasado no son tan diferentes entre sí :) Esto se debe al hecho de que la aparición de Simula marcó el nacimiento de un nuevo concepto: la programación orientada a objetos. Wikipedia da la siguiente definición de POO: La programación orientada a objetos (POO) es una metodología de programación basada en representar un programa como una colección de objetos, cada uno de los cuales es una instancia de una clase específica, y las clases forman una jerarquía de herencia. En mi opinión, es un gran éxito. Recientemente comenzó a aprender Java, pero casi no hay palabras que no le resulten familiares :) Hoy en día, la programación orientada a objetos 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. Estos son C++ (lo utilizan activamente los desarrolladores de juegos de computadora), Objective-C y Swift (escriben programas para dispositivos Apple), Python (el más demandado en el aprendizaje automático), PHP (uno de los lenguajes de desarrollo web más populares), JavaScript (más simple, digamos lo que no hacen) y muchos otros. En realidad, ¿cuáles son estos “principios” de la programación orientada a objetos? Te lo contamos con más detalle.

Principios de programación orientada a objetos

Esto es lo básico. 4 características principales que en conjunto forman el paradigma de programación orientada a objetos. Comprenderlos es la clave para convertirse en un programador exitoso. Principios de la programación orientada a objetos - 3

Principio 1. Herencia

¡La buena noticia es que ya estás familiarizado con algunos de los principios de la programación orientada a objetos! :) Ya nos hemos encontrado con la herencia un par de veces en las conferencias y hemos tenido tiempo de trabajar con ella. La herencia es un mecanismo que le permite describir una nueva clase basada en una existente (principal). En este caso, la nueva clase toma prestadas las propiedades y funcionalidades de la clase principal. ¿Por qué es necesaria la herencia y qué beneficios aporta? En primer lugar, la reutilización de código. Los campos y métodos descritos en las clases principales se pueden utilizar en clases descendientes. Si todos los tipos de automóviles tienen 10 campos comunes y 5 métodos idénticos, solo necesita colocarlos en la clase principal Auto. Puedes usarlos en clases descendientes sin ningún problema. Ventajas sólidas: tanto cuantitativamente (menos código) como, como resultado, cualitativamente (las clases se vuelven mucho más simples). Al mismo tiempo, el mecanismo de herencia es muy flexible y puede agregar la funcionalidad que falta en los descendientes por separado (algunos campos o comportamientos específicos de una clase en particular). En general, como en la vida ordinaria: todos somos similares a nuestros padres en algunos aspectos, pero diferentes de ellos en otros :)

Principio 2. Abstracción

Este es un principio muy simple. Abstracción significa resaltar las características principales y más significativas de un objeto y viceversa: descartar las secundarias e insignificantes. No reinventemos la rueda y recordemos un ejemplo de una antigua conferencia sobre clases. Digamos que estamos creando un archivador de empleados de la empresa. Para crear objetos de empleado, escribimos una clase Employee. ¿Qué características son importantes para su descripción en la ficha de empresa? Nombre completo, fecha de nacimiento, número de seguro social, número de identificación fiscal. Pero es poco probable que en una tarjeta de este tipo necesitemos su altura, color de ojos y cabello. La empresa no necesita esta información sobre el empleado. Por lo tanto, para la clase Employeeestableceremos las variables String name, int age, int socialInsuranceNumbery int taxNumber, y abandonaremos la información que no es necesaria para nosotros, como el color de ojos, y la abstraeremos. Pero si creamos un catálogo de modelos fotográficos para una agencia, la situación cambia drásticamente. Para describir un modelo, la altura, el color de ojos y el color de cabello son muy importantes para nosotros, pero el número TIN no es necesario. Por tanto, en la clase Modelcreamos variables String height, String hair, String eyes.

Principio 3: Encapsulación

Ya lo hemos encontrado. La encapsulación en Java significa limitar el acceso a los datos y la capacidad de cambiarlos. Como puedes ver, se basa en la palabra “cápsula”. En esta “cápsula” escondemos algunos datos importantes para nosotros que no queremos que nadie cambie. Un ejemplo sencillo de la vida. Tienes nombre y apellido. Todos los que conoces los conocen. Pero no tienen acceso para cambiar su nombre y apellido. Este proceso, se podría decir, está “encapsulado” en la oficina de pasaportes: allí sólo puedes cambiar tu nombre y apellido, y sólo tú puedes hacerlo. Otros "usuarios" tienen acceso de sólo lectura a su nombre y apellido :) Otro ejemplo es el dinero en su apartamento. Dejarlos a la vista en medio de la habitación no es una buena idea. Cualquier “usuario” (una persona que se acerque a tu domicilio) podrá cambiar el número de tu dinero, es decir recogelos. Es mejor encapsularlos en una caja fuerte. Sólo tú tendrás acceso y sólo con un código especial. Ejemplos obvios de encapsulación con los que ya ha trabajado son los modificadores de acceso ( private, publicetc.) y los getter-setters. Si el campo agede clase Catno está encapsulado, cualquiera puede escribir:
Cat.age = -1000;
Y el mecanismo de encapsulación nos permite proteger el campo agecon un método de establecimiento, en el que podemos comprobar que la edad no puede ser un número negativo.

Principio 4. Polimorfismo

El polimorfismo es la capacidad de tratar múltiples tipos como si fueran del mismo tipo. En este caso, el comportamiento de los objetos será diferente según el tipo al que pertenezcan. ¿Suena un poco complicado? Vamos a resolverlo ahora. Tomemos el ejemplo más simple: los animales. Creemos una clase Animalcon un solo método ( voice()y dos de sus descendientes) Caty Dog.
public class Animal {

   public void voice() {

       System.out.println("¡Voz!");
   }
}

public class Dog extends Animal {


   @Override
   public void voice() {
       System.out.println("¡Guauu!");
   }
}

public class Cat extends Animal {

   @Override
   public void voice() {
       System.out.println("¡Maullar!");
   }
}
Ahora intentemos crear un enlace Animaly asignarle un objeto Dog.
public class Main {

   public static void main(String[] args) {

       Animal dog = new Dog();
       dog.voice();
   }
}
¿Qué método crees que se llamará? Animal.voice()o Dog.voice()? El método de clase se llamará Dog: ¡Guau-guau! Creamos una referencia Animal, pero el objeto se comporta como Dog. Si es necesario, puede comportarse como un gato, un caballo u otro animal. Lo principal es asignar una referencia de tipo general Animala un objeto de una clase descendiente específica. Esto es lógico, porque todos los perros son animales. Esto es lo que queríamos decir cuando dijimos "los objetos se comportarán de manera diferente según el tipo que sean". Si tuviéramos que crear un objeto Cat:
public static void main(String[] args) {

   Animal cat = new Cat();
   cat.voice();
}
el método voice()generaría "¡Miau!" ¿Qué significa “la capacidad de trabajar con varios tipos como si fueran del mismo tipo”? Esto también es bastante fácil. Imaginemos que estamos creando una peluquería para animales. Nuestro peluquero debe poder cortar todos los animales, por eso crearemos un método shear()(“cortar”) con un parámetro Animal: el animal que cortaremos.
public class AnimalBarbershop {

   public void shear(Animal animal) {

       System.out.println("¡El corte de pelo está listo!");
   }
}
¡Y ahora podemos pasar sheartanto objetos Catcomo objetos al método Dog!
public static void main(String[] args) {

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

   AnimalBarbershop barbershop = new AnimalBarbershop();

   barbershop.shear(cat);
   barbershop.shear(dog);
}
Aquí un ejemplo claro: la clase AnimalBarbershoptrabaja con tipos Catcomo Dogsi fueran del mismo tipo. Al mismo tiempo, tienen un comportamiento Catdiferente Dog: usan su voz de manera diferente.

Razones de la aparición de POO

¿Por qué surgió este nuevo concepto de programación, la POO ? Los programadores tenían herramientas que funcionaban: lenguajes procedimentales, por ejemplo. ¿Qué los impulsó a inventar algo fundamentalmente nuevo? En primer lugar, la complicación de las tareas a las que se enfrentaban. Si hace 60 años la tarea de un programador parecía "calcular una ecuación matemática tal o cual", ahora puede sonar como "implementar 7 finales diferentes para el juego STALKER dependiendo de las decisiones que tomara el usuario en los momentos del juego A, B, C, D". , E, F y combinaciones de estas soluciones." Las tareas, como se puede ver, se han vuelto claramente más complejas en las últimas décadas. Esto significa que los tipos de datos se han vuelto más complejos. Esta es otra razón para el surgimiento de la programación orientada a objetos. El ejemplo con la ecuación se puede resolver fácilmente usando primitivas ordinarias; aquí no se necesitan objetos. Pero será difícil incluso describir el problema con los finales del juego sin utilizar algunas clases que has inventado. Pero al mismo tiempo, es bastante fácil describirlo en clases y objetos: obviamente necesitaremos la clase Juego, la clase Stalker, la clase Ending, la clase Decisión del jugador, la clase Momento del juego, etc. Es decir, incluso sin empezar a resolver un problema, podemos imaginar fácilmente en nuestra cabeza “bocetos” de su solución. La creciente complejidad de los problemas ha obligado a los programadores a dividir el problema en partes. Pero en la programación procedimental esto no fue tan fácil. Y muy a menudo el programa era un “árbol” de un montón de ramas con todas las opciones posibles para su funcionamiento. Dependiendo de determinadas condiciones, el programa se ejecutaba por una rama u otra. Para programas pequeños, esta opción era conveniente, pero dividir una tarea grande en partes era muy difícil. Esta necesidad se convirtió en otra razón para el surgimiento de la POO. Este concepto dio a los programadores la capacidad de dividir un programa en un grupo de "módulos" de clases, cada una de las cuales hacía su propia parte del trabajo. Todos los objetos, interactuando entre sí, forman el trabajo de nuestro programa. Además, el código que escribimos se puede reutilizar 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