27
Dec 16

Pildoritas de POO y Java: Polimorfismo

pildoras poo java
Llevo casi desde que comencé con las pildoritas de POO anunciando que "el polimorfismo va a llegaaaaar" y nada, que no llegaba...¡hasta hoy!

El polimorfismo va muy ligado a la herencia, y se apoya en ella para poder generalizar comportamientos de diferentes clases, como si de una se tratara, siendo para nosotros transparente su tipo, siempre y cuando éste herede de una clase Padre común que define la funcionalidad generalizada.

Polimorfismo

El Polimorfismo es el envío de mensajes a objetos de tipos diferentes utilizando la misma sintaxis. En lenguajes con un sistema de tipos dinámicos, es decir, que una variable puede contener todo tipo de valores y su tipo se setea en tiempo de ejecución. No es necesario el uso de herencia para aplicar el polimorfismo pero en lenguajes fuertemente tipados como Java es necesario utilizar una clase común padre de la cual heredarán todos los objetos polimórficos.

Por ejemplo, basándonos en el ejemplo de nuestra anterior pildorita de Herencia, las clases Profesor y Alumno heredan de Persona varios métodos comunes, como el método toString, que además reimplementan de forma específica cada clase hijo a través de la anotación @Override.

Ahora imaginemos que tenemos un método auxiliar en nuestra aplicación que se dedica a mostrar los datos por pantalla de cualquier persona vinculada a la Escuela, Universidad...¿Cómo lo haríamos de forma general utilizando polimorfismo?

public void mostrarDatos() {
		Profesor profe1 = new Profesor(1, "Antonio", "Brena", "1111111K", 52, "M");
		Profesor profe2 = new Profesor(2, "Alicia", "Hernandez", "2222222K", 45, "F");
		Alumno alumno1 = new Alumno(1, "Mar", "Millan", "44444444K", 29, "F");
		Persona trabajador1 = new Persona("Francisco", "García", "33333333K", 39, "M");
		
		List<Persona> lsPersonas = new ArrayList<Persona>();
		lsPersonas.add(profe1);
		lsPersonas.add(profe2);
		lsPersonas.add(alumno1);
		lsPersonas.add(trabajador1);

		for (Persona per : lsPersonas) {
			System.out.println(per.toString());
		}		
	}

El resultado de ejecutar este método es el siguiente:

DATOS DEL PROFESOR:
Nombre: Antonio
Apellidos: Brena
DNI: 1111111K
Edad: 52
Sexo: M

DATOS DEL PROFESOR:
Nombre: Alicia
Apellidos: Hernandez
DNI: 2222222K
Edad: 45
Sexo: F

DATOS DEL ALUMNO:
Nombre: Mar
Apellidos: Millan
DNI: 44444444K
Edad: 29
Sexo: F

DATOS DE LA PERSONA:
Nombre: Francisco
Apellidos: García
DNI: 33333333K
Edad: 39
Sexo: M

Como se puede observar, para nosotros es indiferente el tipo del objeto que estemos invocando, ya que sabemos que todos esos objetos al heredar de la clase padre Persona tendrán obligatoriamente el método toString. Así mismo, si uno de esos objetos tiene una implementación propia de dicho método, ejecutará la implementación especifica de forma transparente para nosotros.

Aquellos lenguajes que tengan interfaces (como es el caso de Java), pueden también implementar el polimorfismo utilizando este recurso, lo que se conoce como composición de objetos. Esta alternativa se considera mejor práctica a la hora de aplicar polimorfismo que el uso de herencia, ya que este solución sólo obliga a que las diferentes clases compartan el tipo y obligatoriedad de implementar los métodos del interfaz, pero no se comparten comportamientos ni atributos. Pero, ¿qué es una interfaz?

Interfaces y Clases Abstractas

Cuando queremos unificar atributos y métodos en una clase padre, como hemos hecho en la clase Persona, pero no queremos que ésta sea instanciable, crearíamos nuestra clase Persona como clase abstracta:

public abstract class Persona {
	 
    private String nombre;
    private String apellidos;
    private String dni;
    private Integer edad;
    private String sexo;
    
    Persona() {
    	super();
    }
    
    public Persona(String nombre, String apellidos, String dni, Integer edad, String sexo) {
    	super();
    	this.nombre = nombre;
    	this.apellidos = apellidos;
    	this.dni = dni;
    	this.edad = edad;
    	this.sexo = sexo;
    }
    
    public String getNombre() {
        return nombre;
    }
 
    public void setNombre(String nombre) {
        this.nombre = nombre;
    }
 
    public String getApellidos() {
        return apellidos;
    }
 
    public void setApellidos(String apellidos) {
        this.apellidos = apellidos;
    }
 
    public String getDni() {
        return dni;
    }
 
    public void setDni(String dni) {
        this.dni = dni;
    }
 
    public Integer getEdad() {
        return edad;
    }
 
    public void setEdad(Integer edad) {
        this.edad = edad;
    }
 
    public String getSexo() {
        return sexo;
    }
 
    public void setSexo(String sexo) {
        this.sexo = sexo;
    }
    
    @Override 
    public String toString() {
        String nuevalinea = System.getProperty("line.separator");
        String resultado = "DATOS DE LA PERSONA: " + nuevalinea + 
                "Nombre: " + this.getNombre() + nuevalinea + 
                "Apellidos: " + this.getApellidos() + nuevalinea + 
                "DNI: " + this.getDni() + nuevalinea +
                "Edad: " + this.getEdad() + nuevalinea +
                "Sexo: " + this.getSexo() + nuevalinea;
 
        return resultado;
    }
    
	@Override
	public boolean equals(Object object) {
		final Persona aux = (Persona) object;
		if (this == object)
	           return true;
		else if (object == null)
	           return false;
		else if (getClass() != object.getClass())
	           return false;
		else if (this.dni.equals(aux.getDni())) {
			return true;
		} else {
			return false;
		}
	}

     public abstract void metodoAbstracto();
}

Por tanto, en nuestro anterior ejemplo tendríamos un error al crear el objeto Persona trabajador1, ya que, como hemos dicho, las clases abstractas no pueden ser instanciadas:

También podemos añadir métodos abstractos. Un ejemplo de ello es el último método que hemos creado en el ejemplo de la clase abstracta Persona, el método metodoAbstracto(), que como se puede observar siquiera tiene cuerpo. Si creamos un método abstracto estaremos obligados a definir la implementación de dicho método en las clases hijas.

¿Y qué es una interfaz? Pues una clase completamente abstracta, es decir, una clase en la que no se implementan métodos, ni hay atributos, excepto aquellos que sean estáticos y/o constantes.

Los interfaces tienen como finalidad definir la forma y comportamiento de una clase.

Por ejemplo, podríamos tener una interfaz IMamifero, que implemente Persona:

public interface IMamifero {
	public void crecer();
	public void reproducirse();
	public void morir();
}

Para que nuestra clase implemente este interfaz, lo indicaremos a través de la palabra reservada implements.

Al hacer esto, como se puede ver en la anterior imagen, tendremos un error en la mayoría de entornos que nos indicará que tenemos que implementar forzosamente los métodos definidos en el interfaz IMamifero:

public class Persona implements IMamifero {
	 
    private String nombre;
    private String apellidos;
    private String dni;
    private Integer edad;
    private String sexo;
    
    Persona() {
    	super();
    }
    
    public Persona(String nombre, String apellidos, String dni, Integer edad, String sexo) {
    	super();
    	this.nombre = nombre;
    	this.apellidos = apellidos;
    	this.dni = dni;
    	this.edad = edad;
    	this.sexo = sexo;
    }
    
    public String getNombre() {
        return nombre;
    }
 
    public void setNombre(String nombre) {
        this.nombre = nombre;
    }
 
    public String getApellidos() {
        return apellidos;
    }
 
    public void setApellidos(String apellidos) {
        this.apellidos = apellidos;
    }
 
    public String getDni() {
        return dni;
    }
 
    public void setDni(String dni) {
        this.dni = dni;
    }
 
    public Integer getEdad() {
        return edad;
    }
 
    public void setEdad(Integer edad) {
        this.edad = edad;
    }
 
    public String getSexo() {
        return sexo;
    }
 
    public void setSexo(String sexo) {
        this.sexo = sexo;
    }
    
    @Override 
    public String toString() {
        String nuevalinea = System.getProperty("line.separator");
        String resultado = "DATOS DE LA PERSONA: " + nuevalinea + 
                "Nombre: " + this.getNombre() + nuevalinea + 
                "Apellidos: " + this.getApellidos() + nuevalinea + 
                "DNI: " + this.getDni() + nuevalinea +
                "Edad: " + this.getEdad() + nuevalinea +
                "Sexo: " + this.getSexo() + nuevalinea;
 
        return resultado;
    }
    
	@Override
	public boolean equals(Object object) {
		final Persona aux = (Persona) object;
		if (this == object)
	           return true;
		else if (object == null)
	           return false;
		else if (getClass() != object.getClass())
	           return false;
		else if (this.dni.equals(aux.getDni())) {
			return true;
		} else {
			return false;
		}
	}

	@Override
	public void crecer() {
		System.out.println("Crece");
		
	}

	@Override
	public void reproducirse() {
		System.out.println("Fornicia");
		
	}

	@Override
	public void morir() {
		System.out.println("R.I.P.");	
	}
}

Al hacer esto, ya sí que podremos ejecutar nuestra aplicación sin errores y, si queremos, hacer polimorfismo con los métodos definidos por la interfaz:

Profesor profe1 = new Profesor(1, "Antonio", "Brena", "1111111K", 52, "M");
		Profesor profe2 = new Profesor(2, "Alicia", "Hernandez", "2222222K", 45, "F");
		Alumno alumno1 = new Alumno(1, "Mar", "Millan", "44444444K", 29, "F");
		Persona trabajador1 = new Persona("Francisco", "García", "33333333K", 39, "M");
		
		List<Persona> lsPersonas = new ArrayList<Persona>();
		lsPersonas.add(profe1);
		lsPersonas.add(profe2);
		lsPersonas.add(alumno1);
		lsPersonas.add(trabajador1);

		for (Persona per : lsPersonas) {
			per.reproducirse();
		}

Consola:

Fornicia
Fornicia
Fornicia
Fornicia

Como veis, el Polimorfismo no es más que el uso más potente de la herencia, pero no es, ni mucho menos, complejo, al igual que tampoco lo son las ideas de clase abstracta e interfaz una vez se entiende el concepto general de Herencia.

Así que nada, si habéis seguido estas pildoritas al pie de la letra podemos ya afirmar (con extremada timidez, eso sí) que comprendéis y entendéis las bases de lo que es la Programación Orientada a Objetos. A partir de ahora, sólo necesitaréis tiempo y práctica para poder desarrollar cualquier aplicación que deseéis con este paradigma y, eso sí, teniendo claros los conceptos fundamentales que os harán desarollar como las personitas, y no como muchos: con los pies.

Y aunque ésta sí será nuestra última pildorita de POO, ni mucho menos será la última de Java. En las próximas semanas os hablaré de las excepciones (un concepto de Java que escapa a la POO pero fundamental a la hora de programar y realizar un correcto tratamiento de errores) y a partir de ahí, ya se verá. Tenía pensado hacer un programa básico como ejemplo resumen de todo lo que hemos visto, y tras esto, seguir entrando en chicha con conceptos de programación más avanzados.

Índice de Pildoritas

Share
20
Dec 16

Pildoritas de POO y Java: Herencia

pildoras poo java
Como ya dejé entrever en anteriores posts de esta serie de artículos, la pildorita de hoy era la madre de todos los corderos. En ella veríamos un concepto fundamental en POO, la Herencia, y el Polimorfismo, un potente recurso que nos servirá para que la herencia adquiera su máximo potencial a partir de la sobrecarga.

De nuevo del dicho al hecho hay un trecho, y dejo patente una vez más lo noob que soy aún en el terreno de los manuales y tutoriales: La segunda parte de la pildorita, el Polimorfismo, al final va a tener su propio post dedicado, ya que se me iba a ir de las malos su extensión y ya se sabe que mejor separar en trocitos cortos, abarcables y fácilmente comprensibles, que en tochos insufribles y con mil ideas de golpe.

Así que nada, tendréis que esperar a la próxima semana para saber que es eso del Polimorfismo.

En fin, al lío.

Herencia

La herencia tiene como meta la extensión y reutilización de código por lo que se utiliza cuando varias clases tienen funcionalidades comunes, en cuyo caso éstas pueden heredar de una clase padre la funcionalidad común.

Por ejemplo, si volvemos a la imagen de la pildorita de introducción a POO, todas las entidades de la imagen son mamíferos, es decir, todos ellos caminan y maman, no obstante, una Persona podrá, por ejemplo, plantearse el sentido de la vida, mientras un Delfín (que sepamos) no. Así mismo, aunque tanto el Delfín como el Humano pueden desplazarse, uno lo hace nadando con su aleta, mientras otro caminando sobre sus dos piernas, por lo que, aunque sus funcionalidad es igual, se implementa de distinta forma.

mamiferos

Para implementar la herencia entre clases en Java se utiliza la palabra reservada extends. Así mismo, veremos por primera vez una anotación, una muy importante a la hora de utilizar herencia, @Override, y la palabra reservada super.

Para entender mejor la herencia partiremos de nuestro socorrido ejemplo de la clase Alumno.

public class Alumno {
	private String nombre;
    private String apellidos;
    private String dni;
    private Integer edad;
    private String sexo;
	
	private int codAlumno;
	private Lis<Asignatura> asignaturas;
	
	public Alumno (int codAlumno, String nombre, String apellidos, String dni, Integer edad, String sexo, List<Asignatura> lsAsignaturas) {
		this.nombre = nombre;
    	this.apellidos = apellidos;
    	this.dni = dni;
    	this.edad = edad;
    	this.sexo = sexo;
		this.codAlumno = codAlumno;
		this.asignaturas = lsAsignaturas;
	}

        public void setCodAlumno(int codAlumno) {
		this.codAlumno = codAlumno;
	}
	public int getCodAlumno() {
		return codAlumno;
	}
	public void setAsignaturas(List<Asignatura> asignaturas) {
		this.asignaturas = asignaturas;
	}
	public List<Asignatura> getAsignaturas() {
		return asignaturas;
	}
	
	public void asignarAsignatura(Asignatura asignatura) {
		asignaturas.add(asignatura);
	}

	public double getNotaMedia() {
		double resultado = 0;
		for (int i = 0; i < asignaturas.size(); i++) {
			Asignatura asig = asignaturas.get(i);
			resultado += asig.getNota();
		}
		return Math.round((resultado != 0 ? resultado / asignaturas.size(): 0));
	}
}

Imaginemos por otra parte, que tenemos una clase Profesor, definida tal que:

public class Profesor {
	private String nombre;
    private String apellidos;
    private String dni;
    private Integer edad;
    private String sexo;
	
	private int codAlumno;
	
	public Alumno (int codAlumno, String nombre, String apellidos, String dni, Integer edad, String sexo) {
		this.nombre = nombre;
    	this.apellidos = apellidos;
    	this.dni = dni;
    	this.edad = edad;
    	this.sexo = sexo;
	this.codAlumno = codAlumno;
	}

        public void setCodAlumno(int codAlumno) {
		this.codAlumno = codAlumno;
	}
	public int getCodAlumno() {
		return codAlumno;
	}

 public String getNombre() {
        return nombre;
    }
 
    public void setNombre(String nombre) {
        this.nombre = nombre;
    }
 
    public String getApellidos() {
        return apellidos;
    }
 
    public void setApellidos(String apellidos) {
        this.apellidos = apellidos;
    }
 
    public String getDni() {
        return dni;
    }
 
    public void setDni(String dni) {
        this.dni = dni;
    }
 
    public Integer getEdad() {
        return edad;
    }
 
    public void setEdad(Integer edad) {
        this.edad = edad;
    }
 
    public String getSexo() {
        return sexo;
    }
 
    public void setSexo(String sexo) {
        this.sexo = sexo;
    }
 
}

Como se puede ver, las clases Alumno y Profesor comparten mucho código replicado. Los campos nombre, apellidos, DNI, sexo y edad, por tanto, se pueden encapsular en una clase padre, que llamaremos Persona y haremos que ambas clases hereden de ella toda esa funcionalidad común.

public class Persona {
	 
    private String nombre;
    private String apellidos;
    private String dni;
    private Integer edad;
    private String sexo;
    
    Persona() {
    	super();
    }
    
    public Persona(String nombre, String apellidos, String dni, Integer edad, String sexo) {
    	super();
    	this.nombre = nombre;
    	this.apellidos = apellidos;
    	this.dni = dni;
    	this.edad = edad;
    	this.sexo = sexo;
    }
    
    public String getNombre() {
        return nombre;
    }
 
    public void setNombre(String nombre) {
        this.nombre = nombre;
    }
 
    public String getApellidos() {
        return apellidos;
    }
 
    public void setApellidos(String apellidos) {
        this.apellidos = apellidos;
    }
 
    public String getDni() {
        return dni;
    }
 
    public void setDni(String dni) {
        this.dni = dni;
    }
 
    public Integer getEdad() {
        return edad;
    }
 
    public void setEdad(Integer edad) {
        this.edad = edad;
    }
 
    public String getSexo() {
        return sexo;
    }
 
    public void setSexo(String sexo) {
        this.sexo = sexo;
    }

@Override     
public String toString() {
        String nuevalinea = System.getProperty("line.separator");
        String resultado = "DATOS DE LA PERSONA: " + nuevalinea + 
                "Nombre: " + this.getNombre() + nuevalinea + 
                "Apellidos: " + this.getApellidos() + nuevalinea + 
                "DNI: " + this.getDni() + nuevalinea +
                "Edad: " + this.getEdad() + nuevalinea +
                "Sexo: " + this.getSexo() + nuevalinea;
 
        return resultado;
    }
    
	@Override
	public boolean equals(Object object) {
		final Persona aux = (Persona) object;
		if (this == object)
	           return true;
		else if (object == null)
	           return false;
		else if (getClass() != object.getClass())
	           return false;
		else if (this.dni.equals(aux.getDni())) {
			return true;
		} else {
			return false;
		}
	}
}


public class Alumno extends Persona {
	
	private int codAlumno;
	private List<Asignatura> asignaturas;
	
	public Alumno (int codAlumno, String nombre, String apellidos, String dni, Integer edad, String sexo) {
		super(nombre, apellidos, dni, edad, sexo);
		this.codAlumno = codAlumno;
		this.asignaturas = new ArrayList<Asignatura>();
	}
	public void setCodAlumno(int codAlumno) {
		this.codAlumno = codAlumno;
	}
	public int getCodAlumno() {
		return codAlumno;
	}
	public void setAsignaturas(List<Asignatura> asignaturas) {
		this.asignaturas = asignaturas;
	}
	public List<Asignatura> getAsignaturas() {
		return asignaturas;
	}
	
	public void asignarAsignatura(Asignatura asignatura) {
		asignaturas.add(asignatura);
	}

	public double getNotaMedia() {
		double resultado = 0;
		for (int i = 0; i < asignaturas.size(); i++) {
			Asignatura asig = asignaturas.get(i);
			resultado += asig.getNota();
		}
		return (resultado != 0 ? resultado / asignaturas.size(): 0);
	}

@Override 
    public String toString() {
        String nuevalinea = System.getProperty("line.separator");
        String resultado = "DATOS DEL ALUMNO: " + nuevalinea + 
                "Nombre: " + this.getNombre() + nuevalinea + 
                "Apellidos: " + this.getApellidos() + nuevalinea + 
                "DNI: " + this.getDni() + nuevalinea +
                "Edad: " + this.getEdad() + nuevalinea +
                "Sexo: " + this.getSexo() + nuevalinea;
 
        return resultado;
    }
}


public class Profesor extends Persona {
	private int codProfesor;
	
	public Profesor (int codProfesor, String nombre, String apellidos, String dni, Integer edad, String sexo) {
		super(nombre, apellidos, dni, edad, sexo);
		this.codProfesor = codProfesor;
	}
	public void setCodProfesor(int codProfesor) {
		this.codProfesor = codProfesor;
	}

	public int getCodProfesor() {
		return codProfesor;
	}

@Override 
    public String toString() {
        String nuevalinea = System.getProperty("line.separator");
        String resultado = "DATOS DEL PROFESOR: " + nuevalinea + 
                "Nombre: " + this.getNombre() + nuevalinea + 
                "Apellidos: " + this.getApellidos() + nuevalinea + 
                "DNI: " + this.getDni() + nuevalinea +
                "Edad: " + this.getEdad() + nuevalinea +
                "Sexo: " + this.getSexo() + nuevalinea;
 
        return resultado;
}

Por tanto, la clase Persona encapsula toda la funcionalidad común, la cual heredan las clases Profesor y Alumno. Cualquier hijo de la clase Persona, ya sea Profesor o Alumno, podrá invocar a los métodos heredados por su clase padre.

Es importante aclarar, eso sí, que sólo se heredarán aquellos elementos con visibilidad Protected o Public, como vimos en la pildora de visibilidad muy por encima. Por ejemplo, desde la clase Alumno no podemos acceder directamente al DNI con un super.dni, pero sí que podemos hacerlo a través de los métodos setDNI y getDNI, los cuales son públicos.

Hemos creado dos nuevos métodos comunes, equals y toString, que como se puede ver llevan una anotación, @Override. Esto significa que es un método heredado que se va a reescribir para tener una conducta específica y adaptada a la clase hijo. Por ejemplo, los métodos toString de Alumno y Profesor, como se puede ver, devuelven un texto personalizado para esas clase, es decir, sobrescribe el método heredado genérico para cualquier Persona.

Y os preguntareis, ¿y los métodos equals y toString de la clase padre Persona? ¿Por qué tienen también la anotación @Override? Pues porque estos métodos también son heredados. En Java todos los objetos heredan de la clase Object y la clase Object tiene definidos métodos básicos, como toString o equals.

Por último, otra palabra reservada en herencia que utilizaremos mucho es super, la cual tiene una funcionalidad similar a this. Mientras que this, la que ya conocemos, hace mención a la clase en sí, super hacer mención a su clase padre. Por eso, para llamar al constructor de la clase Persona utilizamos la palabra super. De la misma forma, si por ejemplo quisiéramos utilizar el método toString de la clase padre dentro de un método de, por ejemplo, Alumno, utilizaríamos la sentencia super.toString().

Y ya está, no hay más misterio. Como veis, la herencia, aunque potente, es muy sencilla de implementar y entender. En la próxima pildorita veremos la herencia en todo su esplendor con el Polimorfismo y ya con eso, podremos decir que ya sí que sí entendéis la Programación Orientada a Objetos y podéis animaros sin miedo a empezar a programar vuestras propias aplicaciones en Java, C#, o cualquier otro lenguaje POO. No obstante, hay algunas cosas ajenas a la POO pero muy importantes en Java, como las Excepciones, que daremos en otra pildorita extra y con los que no sólo podremos programar en POO, sino tener un buen control de los errores.

Índice de Pildoritas

Share
14
Dec 16

Pildoritas de POO y Java: Relaciones entre Clases

pildoras poo java
En la anterior pildorita os dije que hablaríamos de la Herencia y el Polimorfismo, y aunque esa pildorita está prácticamente terminada en borradores, dándole vueltas a las siguientes pildoritas, me daba cuenta que la que tenía planteada como continuación debía de ir antes, es decir, ésta, sobre relaciones entre clases. Así que nada, esto significa más espera entre la anterior pildorita y ésta, pero el lado bueno es que la siguiente la sacaré en breves.

Llevo unos 7 años trabajando en el desarrollo software y he pasado por multitud de proyectos de gran envergadura. Si algo tengo claro en todos estos años, es que se hace muy mal código - por diversos motivos que no vienen al caso - y que dónde más se falla es, precisamente, en las relaciones de clases: códigos espagueti, pésima modularización y encapsulación... Todos esos problemas vienen, en la mayoría de casos, porque no se tienen del todo claro las relaciones entre clases en la parte más importante del desarrollo, el diseño. Es por eso que antes de entrar en temas de Herencia (algo que muchos desarrollores sí que comprenden bien), creo que es mejor para el aprendizaje de los anteriores conceptos que veamos este tema, que permite asentarlos. Ya habrá tiempo de entrar en la siguiente relación, la generalización, ya que la Herencia no deja de ser también una relación de dos clases.

En la anterior pildorita vimos lo que era un mensaje, y que cuando un objeto lanza un mensaje a otro, estos se comunican y colaboran entre sí. Se dice que existe una Relación entre dos clases si dos objetos de las respectivas clases colaboran entre sí.

Hay tres tipos de relaciones entre clases que a continuación veremos de forma más detallada: Composición, asociación y uso.

Para mayor comprensión de las mismas, utilizaremos el siguiente ejemplo, donde se pueden ver los tres tipos de relaciones:

public class Alumno {
	private String nombre;
    private String apellidos;
    private String dni;
    private Integer edad;
    private String sexo;
	
	private int codAlumno;
	private Lis<Asignatura> asignaturas;
	
	public Alumno (int codAlumno, String nombre, String apellidos, String dni, Integer edad, String sexo, List<Asignatura> lsAsignaturas) {
		this.nombre = nombre;
    	this.apellidos = apellidos;
    	this.dni = dni;
    	this.edad = edad;
    	this.sexo = sexo;
		this.codAlumno = codAlumno;
		this.asignaturas = lsAsignaturas;
	}

        public void setCodAlumno(int codAlumno) {
		this.codAlumno = codAlumno;
	}
	public int getCodAlumno() {
		return codAlumno;
	}
	public void setAsignaturas(List<Asignatura> asignaturas) {
		this.asignaturas = asignaturas;
	}
	public List<Asignatura> getAsignaturas() {
		return asignaturas;
	}
	
	public void asignarAsignatura(Asignatura asignatura) {
		asignaturas.add(asignatura);
	}

	public double getNotaMedia() {
		double resultado = 0;
		for (int i = 0; i < asignaturas.size(); i++) {
			Asignatura asig = asignaturas.get(i);
			resultado += asig.getNota();
		}
		return Math.round((resultado != 0 ? resultado / asignaturas.size(): 0));
	}
}

 

Composición

Es la relación que se constituye entre el todo y la parte. En otras palabras, existe una relación de composición entre la clase A y la clase B, cuando la clase A "tiene un" objeto de la clase B.

Esta colaboración se traduce en la delegación de la clase todo a las partes de ciertas acciones determinadas para implementar la funcionalidad global.

Con esta colaboración se respetará el principio de encapsulación y modularidad por parte de las clases que componen a la clase A.

A la hora de plasmar en código esta relación con los conceptos que hemos visto en las anteriores pildoritas, esto se traduce en un atributo de la clase B en la clase A. Por tanto, tendrá una visibilidad privada y no es versátil, es decir, no puede ser intercambiable por otros objetos. Así mismo, tendrá una duración en la colaboración no momentánea en el tiempo.

Es el caso del atributo codAlumno de nuestra Clase de ejemplo Alumno. Si hiciéramos una clase Profesor, no tendría sentido introducir un código de alumno, por tanto, no es una entidad versátil. Así mismo, el código de alumno se utilizará en muchas funcionalidades de la clase Alumno, ya que es un identificador único similar al DNI. Así mismo ocurre con el resto de atributos que identifican inequívocamente a un Alumno, como nombre, apellidos, DNI...todos aquellos datos que se inicializan a la hora de construir el objeto y que existirán durante todo el ciclo de vida del objeto Alumno.

 

Uso

Es la relación que se establece de forma momentánea entre un objeto cliente (pide algo) y un objeto servidor (suministra ese algo). Por tanto, el objeto de la clase A enviará un mensaje a un objeto de la clase B en un momento dado sin dependencias futuras. Así mismo, el uso de la clase B no dependerá únicamente de la clase A, sino que podrá ser utilizada por otras muchas clases.

Esto significa que la clase A, la cliente, tendrá como parámetro o valor devuelto de un método un objeto de la clase servidora B si esa colaboración es pública, y como un objeto local dentro de un método si es una colaboración privada. La versatilidad de ser intercambiada la clase B por otra, es, por tanto, elevada.

Por ejemplo, el método getNotaMedia() de la clase Alumno, redondea el resultado final utilizando la clase Math e invocando a su método round. Esta clase no es necesaria obviamente para ese cálculo. Podríamos decidir no redondear, o redondear nosotros creando un método propio que realice esta funcionalidad.
 

Aociación

La asociación es una relación de uso donde la relación entre la clase A y la clase B sí que perdura en el tiempo, es decir, se realiza en diversos momentos del ciclo de vida del objeto A, por lo que se crea una relación de dependencia entre ambos objetos. Al igual que la relación de uso, la responsabilidad de manejar ese objeto B no dependerá únicamente del objeto A, sino que podrá ser utilizado por más objetos de diferentes clases.

La asociación, al ser una relación pública generalmente y de una temporalidad no momentánea, pero teniendo una versatilidad reducida, se traducirá en un atributo en la clase A cliente que apuntará a la clase B servidora.

Un ejemplo de este tipo de relación sería la existente entre el Alumno y las Asignaturas. La clase Asignatura es independiente del Alumno, ya que puede existir sin necesidad de que haya Alumnos matriculados a ella. Así mismo, el Alumno puede estar dado de alta en la universidad sin estar matriculado en ninguna asignatura.
 
Espero que esta pildorita haya sido clara y de verdad afiance conceptos fundamentales ya no en el desarrollo de buenos programas en POO, sino de códigos de calidad bien estructurados y fácilmente mantenibles. Cuando vi este capítulo de la asignatura de Programación II me resultó lioso y no le presté toda la atención que merecía. Me centraba en saber sacar las clases de un problema, definir que atributos tenía, y los métodos y sus funcionalidades. Vaya, estaba anclada en lo que conocía, la imperativa. No fue hasta ya después en Ingeniería del Software que llegué a entender del todo para que servía esto y que, la Programación Orientada a Objetos sin estas relaciones no deja de ser modulada, fallo que luego he visto años más tardo muy extendido en la profesión. Sin entender las relaciones, no se sabe de verdar trabajar con POO y poder de verdad explotar la modularidad y ecapsulación que ofrece.

La siguiente pildorita, sí que sí, será la de Herencia y Polimorfismo, la cual, como comenté antes, está ya acabada, así que en una semana tendréis una nueva dosis javera con la que ya prácticamente habremos acabado esta serie 🙂

Índice de Pildoritas

Share
8
Sep 16

Pildoritas de POO y Java: Atributos y Métodos

pildoras poo java
En la anterior pildorita de POO y Java introducimos el concepto de Visibilidad de una clase, la cual nos da la tan ansiada encapsulación.

No obstante, aunque ya llevamos dos pildoritas viendo atributos y métodos, todavía no hemos ahondado suficiente en ciertos conceptos a tener en cuenta a la hora de utilizarlos, pero que ahora que tenemos claro el concepto de Ámbito, podemos afrontar.

Atributos

Los atributos son las variables y constantes que definen los estados o datos de un objeto. Vimos en la anterior pildorita que, al igual que con el resto de elementos existentes en una clase, los atributos también se ven afectados por los modificadores de visibilidad. No obstante, estos modificadores de visibilidad (public, private, static o final), pueden venir seguidos de los modificadores de las características del atributo (su vida útil, sus posibles cualidades y valores, etc.).

  • static: El modificador static, que vimos en la anterior pildorita, se trata como un modificador de característica, y como vimos ya, especifica que el atributo pertenece a la clase y no a los objetos creados a partir de ella.
  • final: El atributo es una constante, por lo que deberá de tener obligatoriamente un valor inicial. Se suele especificar su nombre en mayúsculas por convención.
  • trascient: El atributo no es serializable, es decir, no puede ser convertido en una cadena de bytes que resulte fácilmente manipulable por red, almacenamiento en ficheros, bases de datos, etc. Utilizando este modificador evitamos que este atributo y su valor se tengan en cuenta a la hora de serializar el objeto que los contiene.
  • volatile: Este modificador indica a Java que este atributo puede ser accedido de forma concurrente por varios hilos de forma simultánea.

Métodos

Los métodos son un conjunto de instrucciones definidas dentro de una clase, que realizan tareas y, por norma general, operan sobre los estados de los atributos de dicha clase.

Así mismo, los métodos son el mecanismo que implementa la comunicación entre objetos, lo que comúnmente se llama Paso de Mensajes.

Un objeto, el emisor, solicita ejecutar uno de sus métodos a otro objeto, con el objetivo de que este realice alguna acción, o devuelva cierta información.

Los métodos así mismo, siguen la misma estructura que las funciones y procedimientos de la programación estructurada y pueden recibir, o no, parámetros, así como devolver, o no, valores.

[modificadores] tipo nombreMetodo ([lista parametros]) {
     // instrucciones
     [return valor;]
}

Los modificadores, que no son obligatorios (los corchetes significan que puede estar, o no), indicarán el ámbito de uso del método, y son los que ya hemos visto en la pildorita de Visibilidad y Ámbito.

Constructores

El constructor es un método especial de la clase que se ejecuta siempre que se crea un objeto de dicha clase. Sirve para inicializar los estados del objeto y que sus atributos siempre contengan valores válidos.

Una clase puede tener uno o más constructores. Así mismo, si no se define un constructor, el compilador crea automáticamente el constructor por defecto, un constructor sin parámetros que no hace nada y en el que los atributos del objeto se inicializan a los predeterminados por el sistema.

Para que un método sea interpretado como constructor de una clase debe tener las siguientes características:

  • Tiene el mismo nombre que la clase que contiene
  • No puede devolver ningún valor, ni siquiera el valor void
  • Es público, para que pueda invocarse desde cualquier parte donde se quiera crear un objeto de dicha clase
  • No se hereda

Por ejemplo, volviendo al ejemplo de Persona, cuando creábamos un objeto de este tipo en la clase PruebaPersona, lo hacíamos a través de la sentencia, Persona mar = new Persona();, dicha sentencia llama al constructor por defecto, public Persona();

Si quisiéramos, podríamos crear un nuevo constructor que inicialice los atributos a los valores pasados por parámetro, y así nos ahorraríamos las sentencias de set como mar.setNombre("Mar"), en la que dábamos valor a dicho atributo.

public class Persona {
	 
    private String nombre;
    private String apellidos;
    private String dni;
    private Integer edad;
    private String sexo;
    
    public Persona(String nombre, String apellidos, String dni, Integer edad, String sexo) {
    	super(); // Se llama al constructor por defecto de la clase superior, Object, ya que no se hereda. No es necesario en este caso, pero por convención se pone siempre
    	this.nombre = nombre;
    	this.apellidos = apellidos;
    	this.dni = dni;
    	this.edad = edad;
    	this.sexo = sexo;
    }

Ahora bien, al definir nosotros un constructor, el compilador dejará de crear el constructor por defecto, por lo que, en caso de querer un constructor sin parámetros, deberemos definirlo nosotros también. ¿Y como hacemos esto? Gracias a la Sobrecarga de métodos.

Sobrecarga de métodos

La sobrecarga de métodos es la creación de varios métodos con el nombre, pero con firmas diferentes.

La firma de un método se compone del nombre, la lista de argumentos y el dato devuelto. No obstante en Java, esto último no se tiene en cuenta, por lo que la firma es la combinación del nombre, y el número y tipo de argumentos.

Por ejemplo, los dos constructores de nuestro anterior ejemplo, tienen firmas diferentes por lo que el intérprete es capaz de diferenciarlos aunque tengan el mismo nombre.

public Persona(String nombre, String apellidos, String dni, Integer edad, String sexo) {
	this.nombre = nombre;
    	this.apellidos = apellidos;
    	this.dni = dni;
    	this.edad = edad;
    	this.sexo = sexo;
}

public Persona() {
	super();
}
 

La sobrecarga de métodos da pie a un concepto mucho más amplio conocido como Polimorfismo, pero esto ya es temática para la próxima pildorita, en la cual veremos también otro concepto fundamental de la Programación Orientada a Objetos: la Herencia.

Índice de Pildoritas

Share
6
Jul 16

Carta de dimisión como consejera de Podemos Alcorcón

Como la mayoría de personas que conforman el Círculo de Alcorcón saben, hace 2 meses decidí dimitir como Consejera Ciudadana de Podemos Alcorcón. No lo he hecho oficial hasta ahora principalmente por no perjudicar la campaña de mis compañeros, dando razones contrarias al sentir mayoritario de las bases de mi municipio. Siempre entendí este cargo como un puesto de portavocía, y así es como lo acabo. Sería, bajo mi punto de vista, amoral dar argumentos como consejera (aunque sea dimitiendo) que perjudiquen a la mayoría.

Estas semanas, después del batacazo electoral, tampoco he visto lugar a publicarlo, pero pensando fríamente, ¿cuándo ha habido un momento de tranquilidad en estos dos años de Podemos? Hoy serán las negociaciones, mañana un Vistalegre, pasado otras elecciones, y así ad infinitum. Ahora que la resaca electoral ha pasado, ¿qué mejor momento?

Llegué a Podemos porque era una herramienta ciudadana, una nueva forma de hacer política alejada de las dinámicas de siempre donde los egos y los intereses propios siempre priman. Me acerqué a lo que antes era un movimiento para acabar con la parte representativa (o al menos limitarla al máximo) de nuestra democracia, la cual sigo considerando como uno de los grandes cánceres de la misma. Me presenté a consejera como portavoz de aquellas que pusieron su confianza en mí, siguiendo siempre los designios de los de abajo, y no los de arriba. Pero eso ya no es Podemos. Así lo decidieron en Vistalegre hace más de un año los simpatizantes, y así lo decidió hace unos meses la inmensa mayoría al votar a favor de la confluencia con una un partido tradicional.

No sirvo para las tramas de juego de tronos, para las partidas de Risk, ni para seguir a líderes ciegamente por carismáticos que sean si no me dan argumentos. Me pone enferma tener que pelear con aquellas que deberían ser mis hermanas por sillones que no me pertenecen. No soy capaz de primar votos a principios y mucho menos primar mis principios personales por encima de los del resto. En definitiva, no soy capaz (y por eso jamás antes había militado en un partido político) de ser parte activa de la vieja política.

Se habla ahora de si quizás esta visión idílica tan 15M es de soñadores, de ilusos, de que en la tesitura actual en la que se encuentra Podemos hay que tirar por fórmulas más tradicionales y "realistas". El eterno debate vuelve una vez más: ¿Reformismo o Revolución? ¿Rosa de Luxemburgo o Bernstein?.

Ese sentir tan mayoritario en gran parte tiene razón, y una excelente muestra son los resultados electorales. La gente no está empoderada y sin empoderamiento ciudadano es difícil conseguir una victoria en las instituciones por vías que requieren de gente formada e informada. Tocan pues, las viejas dinámicas.

Deseo de veras a aquellos compañeros capaces de jugar en estas dinámicas y mantener sus valores sin morir en el intento (con los cuales he coincidido en este Consejo Ciudadano) mucha suerte en el proceso de transformación interna necesario en Podemos. Mucha suerte llevando a cabo un programa reformista en nuestras instituciones y manteniendo esos cambios en el tiempo. Ojala la historia de hace un siglo no vuelva a repetirse y sí estemos preparados para el reformismo.

Por mi parte agradezco de veras el tiempo compartido con todas las personas del Círculo, agradezco salir de aquí con grandes amigos en mi mochila y con mi conciencia como ciudadana activa y repleta de ganas de seguir luchando. Gracias a Podemos se lo que supone trabajar y esforzarse por mejorar las cosas, y se la felicidad inmensa que se siente consiguiendo a través de ese esfuerzo una victoria conjunta, por pequeña que sea.

Gracias a mi tiempo en Podemos seguiré militando, pero donde considero que hace falta: en los movimientos sociales que busquen el empoderamiento ciudadano, la formación de un pueblo, que bajo mi humilde opinión, aun necesita mucho que aprender para que un nuevo sistema sea factible.

Muchas gracias a todas las que confiasteis en mi como consejera y siento de veras no cumplir con todo mi mandato, pero viendo los resultados de los últimos referéndum llevados a cabo desde Podemos, no sería una portavoz digna de vuestro sentir.

Seguimos por caminos separados, pero seguimos 🙂

Atentamente,
Mar Millán García.

Share
24
May 16

Pildoritas de POO y Java: Visibilidad y ámbito

pildoras poo java

En la anterior píldora de POO y Java vimos que en la Programación Orientada a Objetos definimos clases, las cuales una vez se instancian son objetos concretos de esa entidad, con su propio estado.

Así mismo, sabemos que las clases y objetos se componen de atributos y métodos, es decir, estados y acciones sobre esos estados. Vimos la manera de definir variables (atributos) y funciones (métodos) en los primeros capítulos de Imperativa, no obstante, en POO hay que tener en cuenta nuevos conceptos propios del paradigma. El fundamental es la Visibilidad, la cual nos da la tan ansiada encapsulación. También debemos conocer cierto concepto previo utilizado en Java y que afecta a la definición de lo qué es visibilidad: Los paquetes.

Para mayor claridad de los conceptos, utilizaremos variaciones en el ejemplo inicial de la anterior pildorita, por lo que es recomendable tenerla abierta en otra pestaña.
 

Paquetes

Los paquetes no son más, siendo muy burdos, que carpetas, y sirven para organizar nuestras clases y darles un nombre único. Los paquetes además, como ocurre con las carpetas, se organizan en una estructura de árbol. Cuando creamos un paquete, se crea una estructura de directorios asociados.

En la anterior pildorita se definió una clase y aunque no se llegó a explicar, la primera línea con la palabra package, indica el paquete donde se encuentra alojada.

// Directorio donde se encuentra la clase Persona y PruebaPersona: 
// ejemplo1/persona
package ejemplo1.persona

carpetas
Así mismo, cuando utilicemos una clase del mismo paquete en otra clase, no tendremos que especificar su ruta. Si no es el caso, utilizaremos la palabra import seguida del paquete y clase.

import ejemplo1.persona.Persona

 

Visibilidad y acceso

La visibilidad, o vista, nos indica por quién es accesible un determinado elemento y es aplicable tanto a clases, como a atributos y métodos. Para diferenciar la visibilidad de un elemento, se utilizan los modificadores de acceso, palabras reservadas que especifican el tipo de visibilidad de dicho atributo, método, etc.

Hay cuatro tipos de modificadores: public, private, protected, default y static.

public

La vista public permite acceder al elemento desde cualquier clase del espacio de trabajo. Un ejemplo de esta vista es la de todos los métodos de la clase Persona o la de su atributo codigoUnico. Como vimos, desde PruebaPersona se accede a él sin necesidad de métodos intermedios.

package ejemplo1.persona;

public class Persona {
 
    public String codigoUnico; 
    
    public String toString() {
        String nuevalinea = System.getProperty("line.separator");
        String resultado = "DATOS DE LA PERSONA: " + nuevalinea + 
                "Codigo Unico: " + this.codigoUnico + nuevalinea +
                "Nombre: " + this.getNombre() + nuevalinea + 
                "Apellidos: " + this.getApellidos() + nuevalinea + 
                "DNI: " + this.getDni() + nuevalinea +
                "Edad: " + this.getEdad() + nuevalinea +
                "Sexo: " + this.getSexo() + nuevalinea;
 
        return resultado;
    }
}

package ejemplo1.persona

public class PruebaPersona {
 
    public static void main(String[] args) {
         
        Persona mar = new Persona();        
        mar.codigoUnico = "112";
        System.out.println(mar.toString());
         
    }
}

private

La vista private, por el contrario, sólo permite que el elemento sea utilizado por otros objetos de la misma clase, pero no por elementos de clases diferentes. Como se ve en el ejemplo anterior, el método toString() utiliza los atributos privados sin necesidad de utilizar métodos públicos que devuelvan sus valores. Sin embargo, para poder utilizarse desde la clase PruebaPersona es necesario hacerlo a través de sus métodos set y get.

package ejemplo1.persona;

public class Persona {
	
	private String nombre;
	
	 public String getNombre() {
        return nombre;
    }
 
    public void setNombre(String nombre) {
        this.nombre = nombre;
    }
}

package ejemplo1.persona

public class PruebaPersona {
 
    public static void main(String[] args) {
         
        Persona mar = new Persona();        
        mar.setNombre("Mar");
        System.out.println("El nombre de la persona es: " + mar.getNombre());
         
    }
}

¿Y que pasaría si intentaramos acceder a un atributo privado? Por ejemplo, el DNI:
private-example
Como se puede ver, se muestra un error pre-compilación, y se nos sugiere o bien cambiar la visibilidad del atributo - a public, por ejemplo - o utilizar un método set, como se hace en la línea anterior.

protected

La vista protected indica que un elemento es accesible desde una clase del mismo paquete, o por una clase que herede de la clase en la que este elemento se encuentra, sin importar el paquete. Una vez más, dejaremos aparcada la herencia, la cual requiere una pildorita por si sola. Cuando toque explicaremos más en profundidad este aspecto.

default

La vista default, que se puede también indicar sin poner ningún modificador de acceso delante del elemento, permite al elemento ser utilizado desde cualquier clase del mismo paquete.

public class Persona {
 
    String codigoUnico; 

}

package ejemplo1.persona

public class PruebaPersona {
 
    public static void main(String[] args) {
         
        Persona mar = new Persona();        
        mar.codigoUnico = "112";
        System.out.println("El Codigo de Persona es: " + mar.codigoUnico);
         
    }
}

static

Por último, existe el modificador static, el cual indica que el elemento pertenece a la clase y no a las instancias de la misma (objetos). Por ejemplo, como vimos en el ejemplo de la anterior pildorita, el main se declara como static. Esto permite acceder al método main sin necesidad de instanciar la clase que lo contiene.

package ejemplo1.persona;
/**
 * Clase Persona
 * @version 1.0
 * @since 2014
 */
public class Persona {
 
    static int numPersonas = 0;
    private String nombre;
   
   // Esto es un constructor 
   Persona() {
	   numPersonas++;
   }

	public void setNombre(String nombre) {
		this.nombre = nombre;
	}
	
	
	public String getNombre() {
		return nombre;
	}
}

package ejemplo1.persona;
/**
 * Clase Test para probar la clase Persona
 * @version 1.0
 * @since 2014
 */
public class PruebaPersona {
 
    public static void main(String[] args) {
         
        Persona objeto1 = new Persona();
        objeto1.setNombre("Mar");
        
        Persona objeto2 = new Persona();
        objeto2.setNombre("Pepe");
        
        System.out.println("El nombre del objeto 1 es: " + objeto1.getNombre());
        System.out.println("El nombre del objeto 2 es: " + objeto2.getNombre());
        System.out.println("Se han creado " + Persona.numPersonas + " personas");
    }
}

El resultado que tendremos es el siguiente:

El nombre del objeto 1 es: Mar
El nombre del objeto 2 es: Pepe
Se han creado 2 personas

Existen otros modificadores de acceso como native, utilizado para indicar código diferente a Java, trascient, que se utiliza para indicar que este elemento no es persistente, final, para especificar que una variable determinada tendrá un valor fijo, volatile y synchronized, utilizados para la programación concurrente y abstract, para herencia. Al no ser modificadores de acceso alejados del concepto de visibilidad, no entran en esta pildorita, pero ya habrá tiempo de verlos.

Índice de Pildoritas

Share
5
Apr 16

Pildoritas POO y Java: El que mucho abarca... u_U!

pildoras poo java

Ayer entré en este blog y miré la parte de estadísticas de la web, cosa que no miraba desde hacía decenios.

Pese a que el rumbo de este sitio ha virado enormemente a la política, por lo que pude ver la mayoría de mis visitas – cosa que por otra parte me dio una muy buena alegría – llegan a este blog gracias a mis Pildoritas de Bases de Datos y Programación orientada a objetos en Java.

Estuve revisando las pildoritas y bueno, con las de POO se me cayó la cara de vergüenza, literalmente. Subí el último post, la introducción de POO, en noviembre de 2014, que se dice pronto. Desde entonces todo aquel que entra a esta serie de pildoras se encuentra con la “grata” sorpresa de que falta justamente la parte de POO, ¡en unas pildoritas que supuestamente son de POO!

Así que nada, ayer volví a releer las pildoritas, consulté apuntes y recoloqué ideas en mi cabeza, con la clara resolución de terminar los, como mucho, 3 o 4 posts que pueden faltar para concluírlas.

Para este finde espero tener el siguiente post, centrado en los ámbitos de las clases y objetos.

Como ya va siendo tradición en mis posts, una vez más pido disculpas a todas aquellas personas que puedan haberlas leído y se hayan quedado con la frustración de no verlas acabadas.

Share
8
Mar 16

Otro 8M sin igualdad

Otro 8 de Marzo. Otro día de la Mujer que pasa por nuestro calendario sin que las cosas cambien.

Seguimos cobrando menos, un 18,9%, y los puestos de dirección siguen siendo para nosotras terreno vedado, habiendo solamente un 4% de directivas mujeres pese a que actualmente se licencian más mujeres que hombres en la universidad española, y con mejores calificaciones.

Seguimos ocupándonos casi en exclusiva de la crianza de los hijos, y lo que es peor, con una de las bajas por maternidad más precarias de Europa, de tan sólo 14 semanas.

Y el mayor drama de todos: pese a la Ley de Violencia de Género de hace 12 años, seguimos teniendo decenas de asesinadas por violencia machista: cincuenta y siete en 2015, once en lo poco que llevamos de año.

we-can-do-it

Celebramos todos los años el Día de la Mujer, pero nada cambia. Nos dan una rosa, porque somos seres débiles, nos montan manifestaciones y actos, hacen homenajes a las grandes figuras del feminismo y llenan informativos con reportajes llenos de datos, pero, una vez pasa el día, nadie se acuerda de las injusticias que hoy se destacan. ¿Qué tal si nos ponemos manos a la obra el resto de 364 días del año?

Necesitamos revisar la Ley de Violencia de Género y ver en que falla, porque obviamente es insuficiente a la hora de acabar con la lacra de la violencia machista.

Necesitamos legislar para que los salarios de las mujeres jamás sean inferiores que los de los hombres, así como obligar a las empresas a tener cifras paritarias en todos sus puestos.

Necesitamos también, no sólo las mujeres, sino los hombres también, bajas de maternidad y paternidad más amplias y compartidas de forma obligatoria. Que la crianza de nuestros hijos sea de verdad cosa de dos, y no siempre recaiga en nuestras espaldas.

Necesitamos una educación que instruya a nuestros jóvenes sobre la importancia y necesidad de tener una sociedad igualitaria: en colegios, institutos y universidades. Para eso también necesitamos profesores que no relaten temarios como loros, sino profesores concienciados y comprometidos que se crean sus propias enseñanzas.

Necesitamos también menos programas, películas y anuncios que cosifiquen a la mujer y la releguen exclusivamente al terreno de la sexualidad.

En resumidas cuentas, necesitamos trabajar día a día en traer la igualdad a la sociedad, pero no con palabras, sino con leyes y formación. Y sobre todo, tenemos que ser nosotras las que nos empoderemos y luchemos de forma activa por ello, porque no se puede crear un marco igualitario que nos tenga en cuenta si no es a partir de nuestras propias manos.

Artículo publicado en El Boletin:

Otro 8M sin igualdad

Share
29
Dec 15

El partido de la sin-izquierda

psoe-marchito3 Los resultados de las últimas elecciones generales están mostrando, si no era ya algo obvio, la verdadera cara del PSOE. Ese PSOE que ni tiene la S ni la O de sus siglas, ese PSOE que es más una empresa donde hacer carrera profesional y medrar, que un partido que quiera mejorar la situación del país. Un PSOE que pese a actuar en contra de todos sus principios, se sigue definiendo como un partido de izquierdas.

Un partido de izquierdas que en vez de analizar por qué ha sufrido los peores resultados de su historia está más preocupado en pedir la cabeza de Pedro Sánchez.

Un partido de izquierdas donde muchos piden enfervorecidos que se ceda ante la troika una vez más y se cree un gobierno de consenso conformado por los benefactores de las injusticias que nos marca Europa.

Un partido de izquierdas que debería liderar una coalición de partidos que dé lugar a un gobierno representativo de la mayoría parlamentaria, de izquierdas, pero que usa excusas peregrinas para no tener que afrontar una legislatura de reformas en contra de sus intereses individuales.

Un partido de izquierdas que no sabe que es el diálogo y la tolerancia, incapaz de sentarse a hablar con Podemos sobre su propuesta de un nuevo modelo territorial y posterior consulta vía referéndum, prefiriendo la imposición autoritaria a una gran porción de la población.

Un partido de izquierdas que defiende en su programa un sistema electoral igualitario pero que sistemáticamente beta cualquier reforma del mismo o peor, donde sus máximos exponentes, como Felipe González, piden reformas electorales que se encaminan a sistemas más injustos.

Un partido de izquierdas, no olvidemos, cuyas máximas figuras viven en consejos de administración de multinacionales a las que siempre beneficiaron en sus pasos por el gobierno, en detrimento de la ciudadanía.

Un partido de izquierdas gobernado por barones y baronesas que descalifican a los candidatos de un partido que representa prácticamente al mismo número de españoles que su partido (Podemos sacó 300.000 votos menos) con frases dignas de las marquesas de otros partidos nada de izquierdas.

Un partido de izquierdas que vive de réditos pasados que no les pertenecen a ellos, sino a la ciudadanía española, y de los cuales no hace más que apropiarse para su propio beneficio.

Un partido de izquierdas plagado de casos de corrupción y cuyos máximos responsables siguen ocupando sus sillones o aun peor, promocionados a sillones más elevados como agradecimiento a tan excelsos servicios a España.

En resumidas cuentas, un partido de izquierdas que no es de izquierdas.

Artículo publicado en El Boletin:

El partido de la sin-izquierda

Share
23
Dec 15

¿Cómo sería una España donde no hubiera votos de primera y segunda?

Este domingo hemos asistido a una de las elecciones españolas más fragmentadas de la historia. Estos resultados son históricos ya no sólo por la fragmentación y variedad de grupos políticos, sino por la entrada de dos nuevos partidos con una amplia representación y que hacen sombra al bipartidismo, pese a tener ambos a La Ley Electoral en contra.

Partido Escaños Votos Totales %
PP 123 7215530 28.72 %
PSOE 90 5530693 22.01 %
Podemos 69 5189333 20.66 %
Ciudadanos 40 3500446 13.93 %
ERC-CATSI 9 599289 2.39 %
DL 8 565501 2.25 %
PNV 6 301585 1.2 %
UP-IU 2 923105 3.67 %
EH Bildu 2 218467 0.87 %
CCa-PNC 1 81750 0.33 %

 

Si miramos los resultados finales, veremos que al PP le cuesta 58.662 votos un escaño y al PSOE 61.452 votos. No obstante, a las nuevas formaciones como Podemos y Ciudadanos, el escaño les cuesta 75.207 y 87.511 votos respectivamente. Como mayor exponente de la injusta ley electoral tenemos a UP-IU, partido que ha necesitado la ingente cantidad de 923.105, casi un millón de votos, por escaño.

Entre PSOE y Podemos, sin ir más lejos, existe una diferencia total de votos de 341.360, pese a eso, el PSOE ha obtenido 21 escaños más. Negocio redondo, una vez más, para el bipartidismo.

Pero, ¿por qué nuestro sistema electoral es tan injusto? ¿Dónde está el fallo?

Aunque muchos señalan a la Ley d'Hondt como máxima responsable, esto no es de todo cierto, ya que Victor d'Hondt pensó su sistema para beneficiar a las minorías. El problema fundamental de nuestro sistema electoral es la circunscripción, ya que d’Hondt deja de ser proporcional cuanto menor es el número de escaños a repartir.

Actualmente nuestra circunscripción es provincial y su objetivo es dar representatividad en el congreso a todos los territorios, sin que ninguno salga perjudicado en la cámara nacional. No obstante, como hay un mínimo de dos escaños por provincia (a excepción de Ceuta y Melilla que les corresponde uno), hay muchas provincias que tienen muchos más escaños de los que realmente les corresponderían por número de habitantes. ¿Cuál es, por tanto, la solución? Cambiar las circunscripciones a niveles poblaciones superiores.

Circunscripción única

La circunscripción única es la opción más proporcional y justa, pero con ella perdemos por completo la representatividad de todos los territorios. Esto no sería un escollo si diéramos al Senado las competencias territoriales que tiene dicha cámara en otros muchos países, pero para ello tendríamos que reformar la constitución, cosa que difícilmente permitirán el PP y PSOE.

Si hubiéramos tenido una circunscripción única en estas elecciones los resultados hubieran sido muy diferentes a los actuales:

Partido Escaños
PP 113
PSOE 87
Podemos 81
Ciudadanos 55
ERC 0
DL 0
PNV 0
UP-IU 14
EH Bildu 0
CCa-PNC 0

 

Todos los partidos nacionalistas quedarían fuera del reparto, ya que no llegan al 3% mínimo de votos que deben sacar los partidos para siquiera entrar en los repartos de escaño.

De no tener dicho margen tendríamos los siguientes resultados:

Partido Escaños
PP 106
PSOE 81
Podemos 76
Ciudadanos 51
ERC 8
DL 8
PNV 4
UP-IU 13
EH Bildu 3
CCa-PNC 1

 

Como veis, hay mayor proporcionalidad entre escaños y número de votos con la circunscripción única, por lo que el mapa del congreso sería hoy muy diferente al actual.

Circunscripción autonómica

La circunscripción autonómica es una solución intermedia que permite respetar la representatividad territorial y que resulta mucho más proporcional al sistema provincial. Como se verá más adelante, de hecho, los resultados son muy parejos a los obtenidos con circunscripción única.

Para el cálculo de los escaños por Comunidad hemos aplicado también el sesgo territorial de dos escaños por Comunidad y luego hemos repartido según población.

35045013 censados / 314 escaños (se han restado los escaños repartidos de forma fija por Comunidad) = 111608.32

¿Qué pasaría entonces si utilizáramos circunscripciones autonómicas?

Andalucía: 59 escaños

Partido Escaños Votos Totales %
PP 18 1292652 29.1 %
PSOE 20 1400399 31.53 %
Podemos 10 749081 16.86 %
Ciudadanos 8 611772 13.77 %
UP-IU 3 256080 5.77 %
PACMA 0 40695 0.92 %
UPYD 0 23134 0.52 %
VOX 0 8974 0.2 %
RECORTES CERO 0 5693 0.13 %
P.C.P.E. 0 5330 0.12 %

Aragón: 11 escaños

Partido Escaños Votos Totales %
PP 4 229196 31.34 %
PSOE 3 168635 23.06 %
Podemos 2 135763 18.56 %
Ciudadanos 2 125903 17.21 %
UP-IU 0 45046 6.16 %
UPYD 0 5791 0.79 %
PACMA 0 5202 0.71 %
EB 0 3851 0.53 %
VOX 0 1839 0.25 %
RECORTES 0 0 1462 0.2 %

Asturias: 10 escaños

Partido Escaños Votos Totales %
PP 3 186586 30.15 %
PSOE 3 144017 23.27 %
Podemos 2 132007 21.33 %
Ciudadanos 1 83885 13.56 %
UP-IU 1 52316 8.45 %
PACMA 0 4482 0.72 %
UPYD 0 3792 0.61 %
EB 0 1861 0.3 %
VOX 0 1684 0.27 %
P.C.P.E. 0 1229 0.2 %

Baleares: 9 escaños

Partido Escaños Votos Totales %
PP 3 140542 29.07 %
Podemos 3 111416 23.05 %
PSOE 2 88542 18.31 %
Ciudadanos 1 71446 14.78 %
MÉS 0 33931 7.02 %
EL PI 0 12902 2.67 %
UP-IU 0 11434 2.37 %
PACMA 0 5106 1.06 %
UPYD 0 2277 0.47 %
RECORTES 0 0 1172 0.24 %

Canarias: 16 escaños

Partido Escaños Votos Totales %
PP 5 283312 28.54 %
PSOE-NCa 4 218241 21.99 %
Podemos 4 231063 23.28 %
Ciudadanos 2 113398 11.42 %
CCa-PNC 1 81750 8.24 %
UP-IU 0 30933 3.12 %
PACMA 0 11874 1.2 %
UPYD 0 4666 0.47 %
UN. PUEBLO ALT. REP. 0 2874 0.29 %
RECORTES 0 0 2648 0.27 %

Cantabria: 6 escaños

Partido Escaños Votos Totales %
PP 3 128852 36.94 %
PSOE 1 78217 22.42 %
Podemos 1 62219 17.84 %
Ciudadanos 1 53182 15.25 %
UP-IU 0 15428 4.42 %
PACMA 0 2924 0.84 %
UPYD 0 2860 0.82 %
VOX 0 895 0.26 %
RECORTES 0 0 522 0.15 %
P.C.P.E. 0 458 0.13 %

Castilla La Mancha: 16 escaños

Partido Escaños Votos Totales %
PP 7 445776 38.17 %
PSOE 5 331388 28.38 %
Ciudadanos 2 160717 13.76 %
Podemos 2 159079 13.62 %
UP-IU 0 41852 3.58 %
PACMA 0 8219 0.7 %
UPYD 0 6136 0.53 %
VOX 0 3594 0.31 %
RECORTES 0 0 1743 0.15 %
P.C.P.E. 0 646 0.06 %

Castilla y León: 20 escaños

Partido Escaños Votos Totales %
PP 8 588194 39.15 %
PSOE 5 337704 22.48 %
Ciudadanos 3 230791 15.36 %
Podemos 3 225824 15.03 %
UP-IU 1 68464 4.56 %
UPYD 0 12910 0.86 %
PACMA 0 8379 0.56 %
VOX 0 4015 0.27 %
RECORTES 0 0 2479 0.17 %
P.C.P.E. 0 2213 0.15 %

Catalunya: 50 escaños

Partido Escaños Votos Totales %
En Comú 13 927940 24.74 %
ERC-CATSI 8 599289 15.98 %
PSC 8 589021 15.7 %
DL 8 565501 15.08 %
Ciudadanos 7 489503 13.05 %
PP 6 417286 11.12 %
unlo.cat 0 64726 1.73 %
PACMA 0 43800 1.17 %
RECORTES 0 0 12741 0.34 %
UPYD 0 7897 0.21 %

Ceuta y Melilla: 3 escaños

En el caso de Ceuta y Melilla, al ser dos provincias pequeñas que por sí mismas no son capaces de sumar un escaño propio, he decidido contemplarlas como una única circunscripción. Si ambas ciudades se presentan juntas sí podrían sumar la población necesaria para tener, a parte de los escaños mínimos, uno propio.

Partido Escaños Votos Totales %
PP 2 27095 43.83 %
PSOE 1 14488 23.43 %
Podemos 0 7836 12.67 %
Ciudadanos 0 8734 14.13 %
UP-IU 0 790 1.27 %
PACMA 0 669 1.08 %
UPYD 0 433 0.07 %
RECORTES 0 0 190 0.03 %

Comunidad Valenciana: 34 escaños

Partido Escaños Votos Totales %
PP 11 837055 31.3 %
Podemos-Compromís 9 671071 25.09 %
PSOE 7 530497 19.84 %
Ciudadanos 6 423556 15.84 %
UP-IU 1 111617 4.17 %
PACMA 0 24916 0.93 %
UPYD 0 17250 0.64 %
CCD 0 9235 0.35 %
VOX 0 7239 0.27 %
SOMVAL 0 6084 0.23 %

Extremadura: 10 escaños

Partido Escaños Votos Totales %
PSOE 4 232879 36 %
PP 4 225230 34.82 %
Podemos 1 81755 12.64 %
Ciudadanos 1 73545 11.37 %
UP-IU 0 19497 3.01 %
PACMA 0 3385 0.52 %
UPYD 0 2610 0.4 %
EU-eX 0 1995 0.31 %
RECORTES 0 0 839 0.13 %
VOX 0 511 0.08 %

Galicia: 23 escaños

Partido Escaños Votos Totales %
PP 9 605178 37.1 %
Podemos-En Marea 6 408370 25.04 %
PSdeG-PSOE 5 347942 21.33 %
Ciudadanos 2 147910 9.07 %
NOS 1 70464 4.32 %
PACMA 0 13205 0.81 %
UPYD 0 8380 0.51 %
RECORTES 0 0 3752 0.23 %
PCPE 0 3213 0.2 %
PT 0 2957 0.18 %

La Rioja: 4 escaños

Partido Escaños Votos Totales %
PP 2 67736 38.35 %
PSOE 1 41875 23.71 %
Podemos 1 27941 15.82 %
Ciudadanos 0 26719 15.13 %
UP-IU 0 7397 4.19 %
UPYD 0 1349 0.76 %
PACMA 0 1165 0.66 %
EB 0 357 0.2 %
RECORTES 0 0 356 0.2 %
P.C.P.E. 0 228 0.13 %

Madrid: 44 escaños

Partido Escaños Votos Totales %
PP 16 1203837 33.46 %
Podemos 9 750477 20.86 %
Ciudadanos 9 676389 18.8 %
PSOE 8 643158 17.88 %
UP-IU 2 189237 5.26 %
UPYD 0 43103 1.2 %
PACMA 0 28302 0.79 %
VOX 0 22441 0.62 %
X LA IZQUIERDA 0 5007 0.14 %
FE LA JONS 0 4688 0.13 %

Murcia: 11 escaños

Partido Escaños Votos Totales %
PP 5 293546 40.44 %
PSOE 2 147524 20.32 %
Ciudadanos 2 128294 17.67 %
Podemos 2 110089 15.16 %
UP-IU 0 22710 3.13 %
PACMA 0 6561 0.9 %
UPYD 0 5418 0.75 %
VOX 0 3271 0.45 %
RECORTES 0 0 1259 0.17 %
EB 0 1062 0.15 %

Navarra: 6 escaños

Partido Escaños Votos Totales %
UPN-PP 2 101901 28.93 %
Podemos 2 80961 22.99 %
PSOE 1 54700 15.53 %
EH BILDU 1 34856 9.9 %
GBAI 0 30554 8.68 %
Ciudadanos 0 24815 7.05 %
UP-IU 0 14489 4.11 %
PACMA 0 2333 0.66 %
UPYD 0 1444 0.41 %
RECORTES 0 0 951 0.27 %

País Vasco: 18 escaños

Partido Escaños Votos Totales %
PNV 5 301585 24.75 %
Podemos 5 316441 25.97 %
PSE-EE 3 161466 13.25 %
EH Bildu 3 183611 15.07 %
PP 2 141556 11.62 %
Ciudadanos 0 49887 4.09 %
UP-IU 0 35815 2.94 %
PACMA 0 7964 0.65 %
UPYD 0 4048 0.33 %
RECORTES 0 0 2415 0.2 %

TOTAL ESPAÑA

Partido Escaños
PP 110
PSOE 83
Podemos 75
Ciudadanos 47
UP-IU 8
ERC-CATSI 8
DL 8
PNV 5
EH Bildu 4
CCa-PNC 1
Nos 1

 

Como se puede observar el resultado es más representativo al número de votos obtenidos por partido y se sigue respetando la representatividad territorial.

Es una prioridad que los partidos en la oposición hagan un gobierno de unidad cuyo objetivo fundamental sea reformar el sistema electoral de cara a una nueva cita electoral. Para ello, no obstante, el PSOE tendría que tener una altura de miras jamás demostrada para ir en contra de su propio beneficio.

¿Cuántas veces más tendremos que votar para tener un sistema electoral que sí nos represente?

Artículo publicado en El Boletin:

¿Cómo sería una España donde no hubiera votos de primera y segunda?

Share