2.def.1 - Métodos

Objetivos

1. Contenidos

1.1 ¿Qué es un método?

Un método es un bloque de código que se escribe para realizar una tarea concreta. Podemos verlo como un subprograma: una pequeña parte del programa que tiene un nombre, puede recibir datos de entrada, puede devolver un resultado y se puede utilizar cada vez que haga falta.

En programación orientada a objetos, los métodos suelen estar dentro de una clase y representan el comportamiento de los objetos. Por ejemplo, un objeto Pedido puede tener métodos para calcular su total, aplicar un descuento, cambiar su estado o mostrar un resumen.

Los métodos nos sirven para organizar el código. En lugar de escribir todas las instrucciones juntas en el programa principal, dividimos el problema en tareas más pequeñas, con nombres claros y fáciles de reutilizar.

Ejemplo profesional: en una aplicación de facturación, no conviene repetir en todas partes el cálculo del IVA. Es mejor crear un método calcularPrecioConIva() y llamarlo siempre que se necesite ese cálculo.

Un método puede tener tres partes importantes:

  • Nombre: indica qué tarea realiza.
  • Parámetros: datos de entrada que el método necesita para trabajar.
  • Resultado: dato que el método puede devolver después de ejecutar su tarea.

1.2 Métodos sin parámetros

Un método sin parámetros no necesita recibir datos externos para ejecutarse. Simplemente realiza una acción usando datos fijos o datos que ya están disponibles dentro del objeto.

Ejemplo en PSeInt: mostrar un separador en pantalla.


Algoritmo DemoMetodoSinParametros
	mostrarSeparador()
	Escribir "Informe de ventas"
	mostrarSeparador()
FinAlgoritmo

SubProceso mostrarSeparador
	Escribir "------------------------------"
FinSubProceso
				

Diagrama de Flujo

Ejemplo en Java: un objeto Informe muestra una cabecera utilizando sus propias propiedades.


class Informe {
	String titulo;
	String fecha;

	void mostrarCabecera() {
		System.out.println("Informe: " + titulo);
		System.out.println("Fecha: " + fecha);
		System.out.println("------------------------------");
	}
}

public class DemoMetodoSinParametros {
	public static void main(String[] args) {
		Informe informe = new Informe();
		informe.titulo = "Ventas del trimestre";
		informe.fecha = "18/05/2026";

		informe.mostrarCabecera();
	}
}
				

La llamada informe.mostrarCabecera() ejecuta el método sobre el objeto informe. No se escriben datos entre los paréntesis porque el método no tiene parámetros.

1.3 Métodos con parámetros de entrada

Un método con parámetros de entrada necesita recibir uno o varios datos para poder realizar su tarea. Esos datos se escriben entre paréntesis al llamar al método.

Los parámetros permiten que el mismo método sirva para diferentes valores. Así evitamos crear un método distinto para cada caso.

Ejemplo en PSeInt: mostrar el precio de un producto con IVA.


Algoritmo DemoParametrosEntrada
	mostrarPrecioConIva(100, 21)
	mostrarPrecioConIva(250, 10)
FinAlgoritmo

SubProceso mostrarPrecioConIva(precio, iva)
	Definir total Como Real
	total <- precio + precio * iva / 100
	Escribir "Precio final: ", total
FinSubProceso
				

Diagrama de Flujo

Ejemplo en Java: un método recibe el porcentaje de descuento que debe aplicar a un pedido.


class Pedido {
	String referencia;
	Double importeBase;
	Double importeFinal;

	void aplicarDescuento(Double porcentajeDescuento) {
		importeFinal = importeBase - importeBase * porcentajeDescuento / 100;
	}

	void mostrarResumen() {
		System.out.println("Pedido: " + referencia);
		System.out.println("Importe base: " + importeBase);
		System.out.println("Importe final: " + importeFinal);
	}
}

public class DemoParametrosEntrada {
	public static void main(String[] args) {
		Pedido pedido = new Pedido();
		pedido.referencia = "PED-1001";
		pedido.importeBase = 200.0;
		pedido.importeFinal = 200.0;

		pedido.aplicarDescuento(15.0);
		pedido.mostrarResumen();
	}
}
				

En la llamada pedido.aplicarDescuento(15.0), el valor 15.0 se entrega al método como dato de entrada. Dentro del método, ese valor se recibe en el parámetro porcentajeDescuento.

1.4 Métodos con parámetros de entrada y valor de salida

Un método también puede recibir datos de entrada y devolver un resultado. En ese caso, el método no solo ejecuta una acción, sino que produce un valor que puede guardarse en una variable, mostrarse por pantalla o utilizarse en otra operación.

En Java, el resultado de un método se devuelve con la palabra return. El tipo de dato escrito delante del nombre del método indica qué tipo de resultado devuelve.

Ejemplo en PSeInt: calcular el total de una línea de factura.


Algoritmo DemoEntradaSalida
	Definir total Como Real
	total <- calcularTotalLinea(4, 19.95)
	Escribir "Total de la línea: ", total
FinAlgoritmo

Funcion total <- calcularTotalLinea(unidades, precioUnitario)
	total <- unidades * precioUnitario
FinFuncion
				

Diagrama de Flujo

Ejemplo en Java: calcular el total de una línea de pedido.


class LineaPedido {
	String producto;
	Integer unidades;
	Double precioUnitario;

	Double calcularTotal() {
		return unidades * precioUnitario;
	}

	Double calcularTotalConDescuento(Double porcentajeDescuento) {
		Double total = calcularTotal();
		return total - total * porcentajeDescuento / 100;
	}
}

public class DemoEntradaSalida {
	public static void main(String[] args) {
		LineaPedido linea = new LineaPedido();
		linea.producto = "Ratón inalámbrico";
		linea.unidades = 6;
		linea.precioUnitario = 24.90;

		Double total = linea.calcularTotal();
		Double totalConDescuento = linea.calcularTotalConDescuento(10.0);

		System.out.println("Total: " + total);
		System.out.println("Total con descuento: " + totalConDescuento);
	}
}
				

Idea clave: un método con salida se puede usar como si fuera un valor. Por eso podemos escribir Double total = linea.calcularTotal();.

1.5 Comparativa de tipos de métodos

La siguiente tabla resume los tipos de métodos más habituales según sus parámetros y su resultado.

Tipo de método Recibe datos Devuelve resultado Ejemplo de uso
Sin parámetros No No necesariamente pedido.mostrarResumen()
Con parámetros de entrada Sí No necesariamente pedido.aplicarDescuento(15.0)
Con entrada y salida Sí Sí Double total = linea.calcularTotalConDescuento(10.0)

En Java, cuando un método no devuelve ningún resultado se utiliza void. Cuando devuelve un resultado, se indica el tipo de dato devuelto, por ejemplo String, Integer, Double o Boolean.

1.6 Cuándo y Cómo escribir un método

Si una parte del código se repite, hay que crear un bucle o escribir un método.

Don't Repeat Yourself (DRY): Este es uno de los tres principios de programación que todos los programadores profesionales conocen. Solo discutimos si debemos aplicarlo cuando el código está repetido dos veces o cuando está repetido tres veces.

Antes de escribir un método conviene pensar en la tarea que debe realizar. Un método bien diseñado debe tener una responsabilidad clara y un nombre que explique su intención.

Pasos recomendados para escribir un método:

  1. Identificar la tarea: decidir qué debe hacer exactamente el método.
  2. Elegir el nombre: utilizar un verbo o una expresión verbal clara, como calcularTotal(), mostrarResumen() o actualizarEstado().
  3. Identificar los datos de entrada: decidir qué datos necesita recibir el método.
  4. Elegir el tipo de cada parámetro: por ejemplo String, Integer, Double o Boolean.
  5. Nombrar los parámetros: usar nombres descriptivos, como porcentajeDescuento o unidadesSolicitadas.
  6. Decidir si devuelve un resultado: si devuelve algo, indicar el tipo; si no devuelve nada, utilizar void.
  7. Escribir el cuerpo del método: programar las instrucciones necesarias para cumplir la tarea.

Convención en Java: los métodos y variables se escriben normalmente en camelCase: calcularTotal, tieneStockSuficiente, actualizarEstado.

Ejemplo de análisis previo:

Decisión Resultado
Tarea Comprobar si hay stock suficiente para atender una venta
Nombre tieneStockSuficiente
Parámetro Integer unidadesSolicitadas
Resultado Boolean

class Producto {
	String codigo;
	String nombre;
	Integer unidadesStock;
	Double precioUnitario;

	Boolean tieneStockSuficiente(Integer unidadesSolicitadas) {
		return unidadesStock >= unidadesSolicitadas;
	}

	Double calcularImporteVenta(Integer unidadesSolicitadas) {
		return unidadesSolicitadas * precioUnitario;
	}

	void descontarStock(Integer unidadesVendidas) {
		unidadesStock = unidadesStock - unidadesVendidas;
	}
}

public class DemoDisenoMetodos {
	public static void main(String[] args) {
		Producto producto = new Producto();
		producto.codigo = "TEC-001";
		producto.nombre = "Teclado mecánico";
		producto.unidadesStock = 12;
		producto.precioUnitario = 49.95;

		Boolean hayStock = producto.tieneStockSuficiente(3);
		Double importe = producto.calcularImporteVenta(3);

		System.out.println("Hay stock: " + hayStock);
		System.out.println("Importe: " + importe);

		producto.descontarStock(3);
		System.out.println("Stock actual: " + producto.unidadesStock);
	}
}
				

En este ejemplo, cada método tiene una tarea concreta. tieneStockSuficiente() comprueba una condición, calcularImporteVenta() calcula un resultado y descontarStock() modifica una propiedad del objeto.

1.7 Paso por valor y paso por referencia en Java

Cuando llamamos a un método, Java entrega los argumentos a los parámetros mediante paso por valor. Esto significa que el método recibe una copia del valor que se le pasa.

En Java no existe el paso por referencia de variables como tal. Lo que ocurre es diferente según el tipo de dato que se pasa:

  • Si se pasa un valor como Integer, Double, Boolean o String, el método recibe una copia de la referencia a un objeto inmutable. Si dentro del método se asigna otro valor al parámetro, la variable original no cambia. (cuando se asigna un nuevo valor a un objeto "inmutable", Java crea un nuevo objeto y asigna a la variable/parámetro la referencia al nuevo objeto).
  • Si se pasa un objeto modificable, el método recibe una copia de la referencia al objeto. Puede modificar el estado interno del objeto, pero no puede cambiar la variable original para que apunte a otro objeto.

Ejemplo 1: intentar cambiar un número


public class DemoPasoValorNumero {
	static void intentarCambiarNumero(Integer numero) {
		numero = numero + 100;
		System.out.println("Dentro del método: " + numero);
	}

	public static void main(String[] args) {
		Integer cantidad = 10;

		intentarCambiarNumero(cantidad);

		System.out.println("Fuera del método: " + cantidad);
	}
}
				

El método muestra 110 dentro, pero fuera la variable cantidad sigue valiendo 10. El cambio solo afecta al parámetro local del método.

Ejemplo 2: modificar el estado de un objeto


class TicketSoporte {
	String codigo;
	String estado;
}

public class DemoPasoValorObjeto {
	static void cerrarTicket(TicketSoporte ticket) {
		ticket.estado = "Cerrado";
	}

	public static void main(String[] args) {
		TicketSoporte ticket = new TicketSoporte();
		ticket.codigo = "TCK-001";
		ticket.estado = "Abierto";

		cerrarTicket(ticket);

		System.out.println(ticket.codigo + ": " + ticket.estado);
	}
}
				

En este caso, el estado del objeto sí cambia. El método recibe una copia de la referencia, pero esa copia apunta al mismo objeto que la variable original.

Ejemplo 3: intentar reemplazar un objeto


class Solicitud {
	String codigo;
	String estado;
}

public class DemoReasignarObjeto {
	static void reemplazarSolicitud(Solicitud solicitud) {
		Solicitud nuevaSolicitud = new Solicitud();
		nuevaSolicitud.codigo = "SOL-999";
		nuevaSolicitud.estado = "Nueva";

		solicitud = nuevaSolicitud;
	}

	public static void main(String[] args) {
		Solicitud solicitud = new Solicitud();
		solicitud.codigo = "SOL-001";
		solicitud.estado = "En revisión";

		reemplazarSolicitud(solicitud);

		System.out.println(solicitud.codigo + ": " + solicitud.estado);
	}
}
				

La variable solicitud del programa principal sigue apuntando al objeto original. Dentro del método se cambia solo el parámetro local, no la variable original.

Resumen: Java siempre pasa los argumentos por valor. En objetos, el valor copiado es una referencia. Por eso un método puede cambiar los atributos del objeto recibido, pero no puede sustituir la variable original por otro objeto.

1.8 Métodos dinámicos y métodos estáticos

En Java podemos diferenciar entre métodos dinámicos y métodos estáticos.

  • Métodos dinámicos: pertenecen a los objetos. Para llamarlos necesitamos tener un objeto creado. Pueden utilizar las propiedades del objeto sobre el que se ejecutan.
  • Métodos estáticos: pertenecen a la clase. Se llaman usando el nombre de la clase y no necesitan que exista un objeto concreto. Suelen usarse para operaciones generales o utilidades.

Ejemplo de método dinámico: el total depende de las propiedades del objeto pedido.


class PedidoOnline {
	String referencia;
	Integer unidades;
	Double precioUnitario;

	Double calcularTotal() {
		return unidades * precioUnitario;
	}

	void mostrarResumen() {
		System.out.println("Pedido: " + referencia);
		System.out.println("Total: " + calcularTotal());
	}
}

public class DemoMetodoDinamico {
	public static void main(String[] args) {
		PedidoOnline pedido = new PedidoOnline();
		pedido.referencia = "WEB-1001";
		pedido.unidades = 5;
		pedido.precioUnitario = 39.90;

		pedido.mostrarResumen();
	}
}
				

La llamada se realiza sobre un objeto concreto: pedido.mostrarResumen(). El resultado depende de los valores guardados en ese objeto.

Ejemplo de método estático: el cálculo del IVA no necesita el estado de ningún objeto.


class CalculadoraPrecios {
	static Double calcularPrecioConIva(Double precioBase, Double porcentajeIva) {
		return precioBase + precioBase * porcentajeIva / 100;
	}

	static Double calcularDescuento(Double precioBase, Double porcentajeDescuento) {
		return precioBase * porcentajeDescuento / 100;
	}
}

public class DemoMetodoEstatico {
	public static void main(String[] args) {
		Double precioConIva = CalculadoraPrecios.calcularPrecioConIva(100.0, 21.0);
		Double descuento = CalculadoraPrecios.calcularDescuento(100.0, 15.0);

		System.out.println("Precio con IVA: " + precioConIva);
		System.out.println("Descuento: " + descuento);
	}
}
				

La llamada se realiza con el nombre de la clase: CalculadoraPrecios.calcularPrecioConIva(100.0, 21.0). No se crea ningún objeto de tipo CalculadoraPrecios.

En PSeInt: no existe la misma diferencia entre métodos dinámicos y métodos estáticos, porque PSeInt no trabaja con clases y objetos como Java. Por eso esta distinción se estudia únicamente en Java.

2. Ejercicios

2.1 Identificar métodos y propiedades

Observa la siguiente descripción de una aplicación de gestión de almacén:

Un producto tiene código, nombre, precio unitario y unidades en stock. El sistema debe poder mostrar la ficha del producto, comprobar si hay stock suficiente, calcular el importe de una venta y descontar unidades del stock.

  1. Indica cuáles serían las propiedades de la clase Producto.
  2. Indica cuáles serían sus métodos.
  3. Clasifica cada método como método sin parámetros, con parámetros de entrada o con entrada y salida.

2.2 Escribir métodos sin parámetros

Crea una clase Empleado con las propiedades String nombre, String departamento y Double salarioMensual. Añade un método mostrarFicha() sin parámetros que muestre los datos del empleado.

2.3 Escribir métodos con parámetros de entrada

Amplía la clase Empleado con un método subirSalario(Double porcentaje). El método debe modificar la propiedad salarioMensual aplicando la subida indicada.

2.4 Escribir métodos con entrada y salida

Crea una clase LineaFactura con las propiedades String concepto, Integer unidades y Double precioUnitario. Añade un método calcularTotal() que devuelva el importe total de la línea.

2.5 Razonar sobre paso por valor

Explica qué mostrará el siguiente código y por qué:


public class EjercicioPasoValor {
	static void cambiar(Integer numero) {
		numero = 99;
	}

	public static void main(String[] args) {
		Integer numero = 10;
		cambiar(numero);
		System.out.println(numero);
	}
}
				

2.6 Llamadas a métodos estáticos

Crea una clase UtilidadesTexto con un método estático normalizarCodigo(String codigo) que devuelva el texto en mayúsculas y sin espacios al principio ni al final. Después, escribe una clase DemoUtilidadesTexto que llame al método usando el nombre de la clase.

Pista: puedes utilizar métodos del sistema como trim() y toUpperCase().

Reto: Métodos para gestionar tickets de soporte

Desarrolla un pequeño programa en Java para representar tickets de soporte técnico. No uses entrada por teclado. Todos los datos deben estar escritos directamente en el código.

Crea una clase TicketSoporte con estas propiedades:

Añade los siguientes métodos dinámicos:

Crea también una clase UtilidadesTickets con estos métodos estáticos:

Por último, crea una clase DemoTickets que:

  1. Cree dos objetos TicketSoporte.
  2. Asigne valores a sus propiedades.
  3. Llame a métodos dinámicos sobre los objetos.
  4. Llame a los métodos estáticos usando el nombre de la clase.
  5. Muestre por pantalla los resúmenes de los tickets y el total de horas estimadas.

3. Bibliografía