Apunte de Programación Orientada a objetos explicando las nociones básicas del paradigma.
Apunte creado por Alejandro Canosa para el plan 111 Mil Programadores
1. Universidad Nacional de Lomas de Zamora
Apunte teórico: Programación Orientada a Objetos,
conceptos y definiciones.
Facultad de Ingeniería
Curso 111 Mil
Profesor Alejandro Canosa
2. Alejandro Canosa, Universidad Nacional de Lomas de Zamora
Curso 111Mil, 2017
2
INTRODUCCIÓN
La programación orientada a objetos es un paradigma el cual consta de definir las entidades
reales como clases con las características reales (atributos o “variables”) y acciones (métodos,
ya sean funciones o procedimientos), las cuales pueden generar varios objetos que pertenecen
a la misma. Este paradigma es el más usado hoy en día debido a las ventajas que proporciona:
Fiabilidad: Al dividir el problema en partes más pequeñas podemos probarlas de
manera independiente y aislar mucho más fácilmente los posibles errores que puedan
surgir.
Mantenibilidad: Los programas son más fáciles de leer y comprender.
Reusabilidad: las clases que definimos pueden ser reutilizadas más adelante en otros
proyectos, sin necesidad de tener que volver a escribirlas de vuelta
Modificabilidad: La facilidad de añadir, suprimir o modificar nuevos objetos nos
permite hacer modificaciones de una forma muy sencilla. Hay una técnica que se
denomina refactorización, la cual consiste en cambiar el algoritmo de un método de
una clase sin cambiar lo que ese método hace, cambiar el cómo hace sin cambiar el
qué hace.
¿QUÉ ES UNA CLASE?
Una clase es un concepto general abstraído de una realidad, que contiene diversas
características y operaciones que llevan a definir el estado y comportamiento,
respectivamente. Se llama estado al valor que tienen los atributos de una clase en un
momento dado y comportamiento al conjunto de operaciones que puede realizar una clase.
A partir de la clase se generan los denominados objetos, que son una instancia de una clase, es
decir, contiene las mismas características del concepto general. Un ejemplo de una clase
puede ser el concepto de Alumno de un curso, con la cual representamos a cada alumno del
curso (cada alumno en particular es un objeto de la clase Alumno).
Arriba se puede ver una representación de la clase alumno, donde se definen los atributos y
comportamientos que tendrán todos los objetos que deriven de esta clase.
Se puede ver a las clases como tipos de datos y a los objetos como variables que usan ese tipo
de datos, teniendo en cuenta que son más complejas en cuestión de propiedades y
operaciones que una simple variable de tipo int.
Hay 4 tipos de clases:
3. Alejandro Canosa, Universidad Nacional de Lomas de Zamora
Curso 111Mil, 2017
3
Entidad: representan un objeto o concepto real, son instanciables (es decir, podemos
crear objetos a partir de esta clase)
Interfaz: son usadas como “puente” para conectar 2 sistemas o para conectar con una
base de datos (No confundir clases de interfaz con interfaz de Java).
Abstracta: una clase que no puede crear objetos, y que puede contener métodos
abstractos (métodos donde solo se define el encabezado y cuyo código debe estar en
las clases que hereden o implementen). Usadas en herencia.
De control: usadas para controlar el flujo del programa. Un ejemplo puede ser una
clase que tenga métodos para verificar el nombre de usuario y contraseña ingresados
en una página web.
Sintaxis de java en cuanto a declaración de clases:
public class Alumno{ //el nombre de la clase debe ir siempre en mayúscula
//defino atributos
private String nombre;
private String apellido;
private int edad;
private int faltas;
private boolean promoción;
//defino constructor (coloco en el espacio de memoria un objeto de esta clase con
//los datos especificados)
public Alumno(String nombre, String apellido, int edad){
this.nombre = nombre;
this.apellido = apellido;
this.edad = edad;
this.faltas = 0; //todo alumno que se inscribe empieza con 0 faltas
this.promocion = true //el alumno al inscribirse puede promocionar
}
public void faltar(){
this.faltas++;
}
public String toString(){
return “Alumno: “ + this.nombre + “ “ + this.apellido;
}
4. Alejandro Canosa, Universidad Nacional de Lomas de Zamora
Curso 111Mil, 2017
4
}
Sintaxis de Java en cuanto a creación de objetos a partir de una clase:
Alumno alumno1 = new Alumno(‘Martin’, ‘Perez’, 23);
Sintaxis de Java para ejecutar un método de una clase sobre cierto objeto con sus atributos
respectivos:
alumno1.getNombre(); //devuelve nombre del alumno1 (Martin)
Entonces alumno1 es un objeto instanciado de la clase Alumno, este objeto tiene los atributos
que se definen dentro de la clases así como sus operaciones. Las clases pueden también tener
objetos como atributos, por ejemplo, una clase Vehiculo que además de especificar los
atributos patente (String), cantidad máxima de pasajeros (int), etc. También puede tener un
objeto llamado dueño o conductor (de la clase Persona):
public class Vehiculo{
private String patente;
private int cantidadMaxPasajeros;
private Persona conductor; //objeto instanciado de la clase persona
}
Todos los objetos tienen un estado y un comportamiento, nos referimos por estado al valor de
los atributos del objeto en un momento determinado, mientras que el comportamiento es el
conjunto de acciones que puede realizar ese objeto (los métodos).
Ya hablamos de los métodos que tiene definidos una clase y de los métodos abstractos usados
en herencia e interfaces, sin embargo, existe también otro tipo de métodos denominados
estáticos (en Java se especifican con la sintaxis static luego de declarar la visibilidad), los
métodos estáticos pueden ser llamados sin necesidad de crear un objeto de la clase donde
está definido, las clases que solo contienen métodos estáticos (actuando como librerías) son
llamadas clases estáticas.
Ejemplo de método estático:
//esto es en una clase denominada Calculadora
public static double dividir(doublé dividendo, doublé divisor){
double resultado = 0;
.
.
5. Alejandro Canosa, Universidad Nacional de Lomas de Zamora
Curso 111Mil, 2017
5
.
return divisor;
}
Ejemplo de llamada a método estático:
Calculadora.dividir(4.0/2.0); //escribo nombre de clase, luego punto, luego escribo el nombre
//de la función estática
Los objetos también tienen un tiempo de vida, el cual inicia con un constructor (son asignados
a memoria) y termina con un destructor (se libera la memoria que ocupan). En Java, si bien
usamos constructor, no es necesario que destruyamos los objetos manualmente, dado que
internamente se revisan los objetos que se dejaron de usar hace bastante tiempo y se
destruye, este programa que revisa y destruye objetos que no se usan mas es conocido como
recolector de basura o Garbage Collector.
Ejemplo de constructor usando la sintaxis de Java repitiendo el de la clase Alumno:
//luego de definir la visibilidad va el nombre de la clase, en este caso la clase es Alumno.
public Alumno(String nombre, String apellido, int edad){
this.nombre = nombre;
this.apellido = apellido;
this.edad = edad;
this.faltas = 0; //todo alumno que se inscribe empieza con 0 faltas
this.promocion = true //el alumno al inscribirse puede promocionar
}
Un objeto puede tener ya valores asignados (las inicializaciones como las de variables que se
han visto en el curso también son valores asignados, nos referimos por ejemplo a darle a algún
atributo el valor inicial 0 como en el ejemplo de arriba) o pueden no tener ninguno, cuando el
objeto es creado en memoria pero no definimos un estado (o valores para sus atributos) tiene
un valor NULO (null en java). Esto quiere decir que hay una porción de memoria donde se
guarda ese valor vacío. Debajo se ve reflejado este caso:
Persona persona; //objeto de clase persona pero con valor nulo.
Persona persona2 = new Persona(‘Fulano’, ‘Mengano’, 30); //objeto con valores asignados
Probar realizar en un archivo Main.java la creación de un objeto a1 a partir de
cierta clase A usando la instrucción new y llamando a su constructor y un objeto a2
a partir de cierta clase A SIN llamar a ningún constructor o darle valores, imprimir
por consola tanto a1 como a2 (usar toString() para la impresión correcta del
objeto).
6. Alejandro Canosa, Universidad Nacional de Lomas de Zamora
Curso 111Mil, 2017
6
¿ASIGNAR OBJETOS ES LO MISMO QUE ASIGNAR VARIABLES?
Por asignación nos referimos a copiar el valor de una variable X a una variable Y, es decir:
int x = 0;
int y = 6;
x = y; //x vale 6 ahora
x = x – 1 //x vale 5 ahora, “y” sigue valiendo 6
Entonces, con los objetos debería aplicarse la misma lógica… sin embargo, esto no es así,
cuando nosotros creamos un objeto, al igual que la variable, le estamos dando un espacio en
memoria, suponiendo que tenemos un objeto a1 y a2, estos tienen 2 direcciones distintas en
memoria, si yo realizo una asignación como a1 = a2, la dirección de memoria del objeto a1
cambia de apuntar al lugar de memoria de a1 a apuntar adonde está guardado a2 en
memoria, es decir, todo cambio en a1 a partir de este momento va a ser reflejado en a2, dado
que ambos “comparten” el mismo objeto.
¿CUÁLES SON LOS PILARES DE LA ORIENTACIÓN A OBJETOS?
Los pilares son los siguientes:
Abstracción
Herencia
Encapsulamiento
Polimorfismo
La abstracción es el proceso en el cual nosotros a partir de un objeto o concepto real
obtenemos las propiedades que necesitamos para reflejarlo en un sistema, sin centrarnos en
detalles que no nos sirven, en otras palabras, aislamos mentalmente este objeto o concepto y
usamos los datos de él que necesitamos en el sistema, sin meter datos que no son útiles a la
hora de programar. La definición de clases a partir de un enunciado es básicamente una
abstracción.
Para entender el encapsulamiento es necesario primero definir la visibilidad, que es una
característica que se define para los atributos y métodos de una clase y consiste en determinar
quién puede acceder a ellos, esta puede ser:
Publica: todos pueden acceder
Protegida: solo lo pueden acceder las clases hijas
Privada: solo lo puede acceder la clase misma.
El encapsulamiento se produce cuando ocultamos los atributos de nuestra clase (haciéndolos
privados) y accediendo a ellos mediante métodos propios de la clase, estos métodos son
denominados getters y setters. Los getters nos dan el valor actual del atributo especificado y
los setters nos permiten cambiar el valor de dicho atributo.
La herencia en objetos ocurre cuando una clase general tiene subdivisiones, es decir, la clase
más general es madre de esas subdivisiones, las cuales heredan sus características. Las clases
7. Alejandro Canosa, Universidad Nacional de Lomas de Zamora
Curso 111Mil, 2017
7
hijas entonces además de sus atributos y métodos propios, tienen además los atributos y
métodos de la clase madre (la visibilidad de estos tiene que ser publica o protegida). La clase
madre puede ser también una clase abstracta, la cual no permite la creación de objetos y
puede contener métodos abstractos (métodos sin un cuerpo definido, que debe ser
implementado en las clases hijas). Un ejemplo de herencia puede ser tener una clase Vehículo
y 2 clases hijas Auto y Motocicleta, si bien son 2 cosas distintas, ambas son vehículos, por eso
heredan de la clase Vehículo y contienen en común esas caracteristicas.
Ejemplo de método abstracto:
public abstract void hacerAlgo(); //solo defino encabezado, la clase hija después definirá el
// método como se hace regularmente
El polimorfismo consta de definir un método en la clase hija cuyo nombre sea igual al de la
clase madre, y que tenga una implementación diferente. Esto no es lo mismo que la
sobrecarga de métodos y el Override. En la sobrecarga de métodos se define un método con el
mismo nombre y distintos parámetros en la misma clase, sin haber herencia de por medio y
el Override lo que hace es definir en la clase hija el mismo método que está en la clase madre y
que tenga la misma implementación en ambas teniendo por diferencia los atributos usados,
por ejemplo, el toString().
¿QUÉ ES UNA INTERFAZ?
La palabra interfaz es bastante común en el mundo del desarrollo, puede referir a 3 cosas:
Interfaz de usuario
Interfaces del sistema
Interfaces de java.
La interfaz de usuario es la parte visual del programa con la que el usuario trabaja, es decir, la
parte de la ventana, botones, etc.
Las interfaces de un sistema son los módulos o clases que unen un sistema A con un sistema B.
Las interfaces de Java, son como “contratos” donde se crean métodos abstractos para que
todas las clases que las implementen definan sus cuerpos. Decimos que una clase implementa
una interfaz cuando usa todos los métodos abstractos que definidos. Las interfaces de Java son
usadas cuando se debe usar herencia múltiple.
8. Alejandro Canosa, Universidad Nacional de Lomas de Zamora
Curso 111Mil, 2017
8
En el ejemplo de arriba, la clase Seguridad hereda tanto de Emergencia como de
ServicioPrivado (también hereda indirectamente de Vehículo). En java, esto no es posible,
dado que si yo llamo a un método que no está en la clase Seguridad, java busca en las clases
madres ese método (siempre y cuando sea público o protegido), si ese método que invoque
esta tanto en Emergencia como en ServicioPrivado, Java no sabe cuál usar de los 2, este
problema es denominado el problema del diamante y podría darse con atributos o cualquier
otro método, y para solucionarlo Java solo permite que se herede de 1 sola clase a la vez, y
para simular la herencia múltiple introdujo el uso de las interfaces.
Aplicando las interfaces, Emergencia y ServicioPrivado son transformados, nótese que ya no
tienen atributos, dado que una interfaz no contiene atributos, solo métodos abstractos,
aquellos que estaban en estas 2 clases fueron removidos y se agregó un getter y setter para
obligar a las clases que las implementen a crear el atributo en el cual están definidos estos
métodos. Por ejemplo, en la interfaz IEmergencia, hay un get y set del atributo estadoSirena,
tanto Policia, Ambulancia y Seguridad deben implementar los métodos y a la vez están
obligados a crear ese atributo dentro de sus propias clases para que puedan ser codificados
9. Alejandro Canosa, Universidad Nacional de Lomas de Zamora
Curso 111Mil, 2017
9
correctamente (es inservible hacer un getter y un setter de un atributo que no existe en una
clase).