¡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.
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 :)
Principios de programación orientada a objetos:
¿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 ".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.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 principalAuto
. 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 claseEmployee
. ¿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 Employee
estableceremos las variables String name
, int age
, int socialInsuranceNumber
y 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 Model
creamos 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
, public
etc.) y los getter-setters. Si el campo age
de clase Cat
no está encapsulado, cualquiera puede escribir:
Cat.age = -1000;
Y el mecanismo de encapsulación nos permite proteger el campo age
con 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 claseAnimal
con un solo método ( voice()
y dos de sus descendientes) Cat
y 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 Animal
y 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 Animal
a 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 shear
tanto objetos Cat
como 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 AnimalBarbershop
trabaja con tipos Cat
como Dog
si fueran del mismo tipo. Al mismo tiempo, tienen un comportamiento Cat
diferente Dog
: usan su voz de manera diferente.
GO TO FULL VERSION