Cómo explicar conceptos de programación orientada a objetos a un niño de 6 años

¿Ha notado que siempre se hacen las mismas preguntas clichés en las entrevistas de trabajo, una y otra vez?

Estoy seguro de que sabes a qué me refiero.

Por ejemplo:

¿Dónde te ves en cinco años?

o peor aún:

¿Cuál consideras que es tu mayor debilidad?

Ugh ... dame un respiro. ¡Considero que responder a esta pregunta es una gran debilidad! De todos modos, no es mi punto.

Por triviales que sean preguntas como estas, son importantes porque dan pistas sobre usted. Tu estado mental actual, tu actitud, tu perspectiva.

Al responder, debe tener cuidado, ya que puede revelar algo de lo que luego se arrepienta.

Hoy quiero hablar de un tipo de pregunta similar en el mundo de la programación:

¿Cuáles son los principios fundamentales de la programación orientada a objetos?

He estado en ambos lados de esta cuestión. Es uno de esos temas que se preguntan con tanta frecuencia que no puedes permitirte no saberlo.

Los desarrolladores junior y de nivel de entrada generalmente tienen que responder. Porque es una manera fácil para que el entrevistador diga tres cosas:

  1. ¿Se preparó el candidato para esta entrevista?

    Puntos de bonificación si escucha una respuesta de inmediato: muestra un enfoque serio.

  2. ¿El candidato ha superado la fase de tutoría?

    Comprender los principios de la programación orientada a objetos (OOP) muestra que ha ido más allá de copiar y pegar de los tutoriales: ya ve las cosas desde una perspectiva superior.

  3. ¿La comprensión del candidato es profunda o superficial?

    El nivel de competencia en esta pregunta a menudo es igual al nivel de competencia en la mayoría de las otras materias . Créeme.

Los cuatro principios de la programación orientada a objetos son encapsulación , abstracción , herencia ,y polimorfismo .

Estas palabras pueden sonar aterradoras para un desarrollador junior. Y las explicaciones complejas y excesivamente largas en Wikipedia a veces duplican la confusión.

Por eso quiero dar una explicación simple, breve y clara de cada uno de estos conceptos. Puede sonar como algo que le explica a un niño, pero en realidad me encantaría escuchar estas respuestas cuando realice una entrevista.

Encapsulamiento

Digamos que tenemos un programa. Tiene algunos objetos lógicamente diferentes que se comunican entre sí, de acuerdo con las reglas definidas en el programa.

La encapsulación se logra cuando cada objeto mantiene su estado privado , dentro de una clase. Otros objetos no tienen acceso directo a este estado. En cambio, solo pueden llamar a una lista de funciones públicas, llamadas métodos.

Entonces, el objeto administra su propio estado a través de métodos, y ninguna otra clase puede tocarlo a menos que se permita explícitamente. Si desea comunicarse con el objeto, debe utilizar los métodos proporcionados. Pero (de forma predeterminada), no puede cambiar el estado.

Digamos que estamos construyendo un pequeño juego de Sims. Hay gente y hay un gato. Se comunican entre sí. Queremos aplicar la encapsulación, por lo que encapsulamos toda la lógica "cat" en unCatclase. Puede verse así:

Aquí el “estado” del gato es las variables privadasmood , hungryy energy. También tiene un método privado meow(). Puede llamarlo cuando quiera, las otras clases no pueden decirle al gato cuándo maullar.

Lo que pueden hacer es definido en los métodos públicossleep() , play()y feed(). Cada uno de ellos modifica el estado interno de alguna manera y puede invocar meow(). Por lo tanto, se realiza la vinculación entre el estado privado y los métodos públicos.

Esta es la encapsulación.

Abstracción

Se puede pensar en la abstracción como una extensión natural de la encapsulación.

En el diseño orientado a objetos, los programas suelen ser extremadamente grandes. Y los objetos separados se comunican mucho entre sí. Por lo tanto, mantener una base de código grande como esta durante años, con cambios en el camino, es difícil.

La abstracción es un concepto que tiene como objetivo aliviar este problema.

Aplicar abstracción significa que cada objeto solo debe exponer un mecanismo de alto nivel para usarlo.

Este mecanismo debería ocultar los detalles internos de la implementación. Solo debe revelar operaciones relevantes para los otros objetos.

Piensa: una máquina de café. Hace muchas cosas y hace ruidos extraños debajo del capó. Pero todo lo que tienes que hacer es poner café y presionar un botón.

Preferiblemente, este mecanismo debe ser fácil de usar y rara vez debe cambiar con el tiempo. Piense en ello como un pequeño conjunto de métodos públicos que cualquier otra clase puede llamar sin "saber" cómo funcionan.

¿Otro ejemplo real de abstracción?

Piense en cómo usa su teléfono:

Interactúas con tu teléfono usando solo unos pocos botones. ¿Qué está pasando debajo del capó? No tiene que saberlo, los detalles de implementación están ocultos. Solo necesita conocer un breve conjunto de acciones.

Los cambios de implementación, por ejemplo, una actualización de software, rara vez afectan la abstracción que utiliza.

Herencia

Bien, vimos cómo la encapsulación y la abstracción pueden ayudarnos a desarrollar y mantener una gran base de código.

Pero, ¿sabe cuál es otro problema común en el diseño de programación orientada a objetos?

Los objetos suelen ser muy similares. Comparten una lógica común. Pero no son del todo iguales. Ugh ...

Entonces, ¿cómo reutilizamos la lógica común y extraemos la lógica única en una clase separada? Una forma de lograrlo es la herencia.

Significa que crea una clase (secundaria) derivando de otra clase (principal). De esta manera formamos una jerarquía.

La clase secundaria reutiliza todos los campos y métodos de la clase principal (parte común) y puede implementar los suyos propios (parte única).

Por ejemplo:

Si nuestro programa necesita gestionar profesores públicos y privados, pero también otro tipo de personas como estudiantes, podemos implementar esta jerarquía de clases.

De esta manera, cada clase agrega solo lo que es necesario mientras reutiliza la lógica común con las clases principales.

Polimorfismo

¡Nos quedamos con la palabra más compleja! Polimorfismo significa "muchas formas" en griego.

Así que ya conocemos el poder de la herencia y lo usamos felizmente. Pero surge este problema.

Digamos que tenemos una clase padre y algunas clases secundarias que heredan de ella. A veces queremos usar una colección, por ejemplo, una lista, que contiene una combinación de todas estas clases. O tenemos un método implementado para la clase principal, pero también nos gustaría usarlo para los niños.

Esto se puede resolver utilizando polimorfismo.

En pocas palabras, el polimorfismo proporciona una forma de usar una clase exactamente como su padre, por lo que no hay confusión con la mezcla de tipos.Pero cada clase hija mantiene sus propios métodos tal como están.

Esto suele suceder al definir una interfaz (principal) que se reutilizará. Describe varios métodos comunes. Luego, cada clase secundaria implementa su propia versión de estos métodos.

Cada vez que una colección (como una lista) o un método espera una instancia del padre (donde se describen los métodos comunes), el lenguaje se encarga de evaluar la implementación correcta del método común, independientemente de qué hijo se pase.

Eche un vistazo a un boceto de implementación de figuras geométricas. Reutilizan una interfaz común para calcular el área de superficie y el perímetro:

Tener estas tres figuras que heredan los padres Figure Interfacele permite crear una lista de mezclado triangles, circlesy rectangles. Y trátelos como el mismo tipo de objeto.

Luego, si esta lista intenta calcular la superficie de un elemento, se encuentra y ejecuta el método correcto. Si el elemento es un triángulo, el triánguloCalculateSurface()se llama. Si es un círculo, entonces el de CirlceCalculateSurface()se llama. Y así.

Si tiene una función que opera con una figura usando su parámetro, no tiene que definirla tres veces: una para un triángulo, un círculo y un rectángulo.

Puede definirlo una vez y aceptar un Figurecomo argumento. Ya sea que pase un triángulo, círculo o rectángulo, siempre que se implementen CalculateParamter(), su tipo no importa.

Espero que esto haya ayudado. Puede utilizar directamente estas mismas explicaciones exactas en las entrevistas de trabajo.

Si encuentra algo que aún es difícil de entender, no dude en preguntar en los comentarios a continuación.

¿Que sigue?

Estar preparado para responder a una de las preguntas clásicas de las entrevistas es genial, pero a veces nunca te llaman para una entrevista.

A continuación, me centraré en lo que los empleadores quieren ver en un desarrollador junior y en cómo destacar entre la multitud cuando buscan trabajo.

Manténganse al tanto.