Pilares de la programación orientada a objetos – Con ejemplos en C# y Java
En esta entrada se van a tratar cuatro pilares de la programación orientada a objetos, estos son los mas comunes en la literatura que son: Abstracción, Encapsulamiento, Herencia y Polimorfismo.
Abstracción
La abstracción nos permite identificar las características y comportamientos con los que se construirá una clase. Es decir que atraves de este pilar es posible reconocer los atributos y métodos de un objeto.
Por ejemplo, un televisor.
Basándonos en la imagen vamos a abstraer este televisor y el resultado son los siguientes atributos y métodos:
Atributos:
- Color
- Tamaño
- Marca
- Decodificador
Métodos (como se comporta):
- Encender
- Apagar
- Cambiar canal
El resultado de abstraer es la clase que nos servirá de plantilla para nuestros objetos y codificarlo en C# seria así:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | using System; /*El resultado de nuestra abstracción es esta clase que nos sirve de plantilla para crear objetos */ public class Televisor{ //Atributos string Color {get;set;} string Marca {get;set;} int Tamanio {get;set;} bool Decodificador {get;set;} //Metodos public void Encender(){ Console.WriteLine("Televisor encendido"); } public void Apagar(){ Console.WriteLine("Televisor apagado"); } public void CambiarCanal(int canal){ Console.WriteLine("Cambio al canal: "+canal); } } |
En Java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | public class televisor { //Atributos private String Color, Marca; private int Tamanio; private boolean Decodificador; //Metodos public void Encender() { System.out.println("Televisor encendido"); } public void Apagar() { System.out.println("Televisor apagado"); } public void CambiarCanal(int canal) { System.out.println("Cambio de canal: " + canal); } public String getColor() { return Color; } public void setColor(String Color) { this.Color = Color; } public String getMarca() { return Marca; } public void setMarca(String Marca) { this.Marca = Marca; } public int getTamanio() { return Tamanio; } public void setTamanio(int Tamanio) { this.Tamanio = Tamanio; } public boolean isDecodificador() { return Decodificador; } public void setDecodificador(boolean Decodificador) { this.Decodificador = Decodificador; } } |
Encapsulamiento
Permite el ocultamiento de la complejidad del código para que no pueda ser visto o modificado por el usuario de manera imprevista e incontrolada.
Por ejemplo, los atributos de una clase, estos son privados y solo se pueden acceder a ellos por medio de los métodos
get
o
set
de cada uno.
En este pilar tenemos a los modificadores de acceso como
public
,
private
y
protected
.
En este ejemplo cambie los modificadores de acceso a privados es decir que solo miembros de la misma clase pueden hacer uso de los mismos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public class Televisor{ //Atributos private string Color {get;set;} private string Marca {get;set;} private int Tamanio {get;set;} private bool Decodificador {get;set;} //Metodos public void Encender(){ Console.WriteLine("Televisor encendido"); } public void Apagar(){ Console.WriteLine("Televisor apagado"); } public void CambiarCanal(int canal){ Console.WriteLine("Cambio al canal: "+canal); } } |
En java tenemos a los métodos
get
y
set
,estos son públicos por defecto.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | public class televisor { //Atributos private String Color, Marca; private int Tamanio; private boolean Decodificador; public String getColor() { return Color; } public void setColor(String Color) { this.Color = Color; } public String getMarca() { return Marca; } public void setMarca(String Marca) { this.Marca = Marca; } public int getTamanio() { return Tamanio; } public void setTamanio(int Tamanio) { this.Tamanio = Tamanio; } public boolean isDecodificador() { return Decodificador; } public void setDecodificador(boolean Decodificador) { this.Decodificador = Decodificador; } } |
Herencia
Este es uno de los pilares más fuertes ya que permite reutilizar código, heredando los métodos y atributos de una clase superior (Llamada clase padre) a una clase derivada (Llamada clase hija), esto significa que se cualquier clase derivada puede hacer uso de los métodos y atributos de su clase superior.
Seguimos con el ejemplo del televisor, al cual ahora mediante la palabra reservada
abstract
que convierte a clase en abstracta y nos permite crear clases que deriven de la misma. El ejemplo de esto en C# seria algo así:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | using System; /*El resultado de nuestra abstracción es esta clase que nos sirve de plantilla para crear objetos */ public abstract class Televisor{ //Atributos public string Color {get;set;} public string Marca {get;set;} public int Tamanio {get;set;} public bool Decodificador {get;set;} //Metodos public void Encender(){ Console.WriteLine("Televisor encendido"); } public void Apagar(){ Console.WriteLine("Televisor apagado"); } public void CambiarCanal(int canal){ Console.WriteLine("Cambio al canal: "+canal); } } // La Tv Digital hereda las características de la clase padre class TVDiginal:Televisor{ public TVDiginal(){ //Esta clase puede acceder a los atributos de su padre Decodificador=true; } } |
Cabe mencionar que para especificar una herencia, utilizamos
:
seguido de el nombre de la clase superior
En Java la cosa no cambia mucho, aquí se utiliza la palabra reservada
extends
para especificar que esta clase hereda de otra superior (abstracta)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | public abstract class televisor { //Atributos String Color, Marca; int Tamanio; boolean Decodificador; //Metodos public void Encender() { System.out.println("Televisor encendido"); } public void Apagar() { System.out.println("Televisor apagado"); } } //en Java cada clase va separada en su propio archivo .java public class TvDigital extends televisor{ public TvDigital() { Decodificador=true; } } |
Polimorfismo
Esta característica permite definir un método con un nombre y definir su comportamiento y parámetros según sea necesario.
Por ejemplo el área de una figura. Estamos consientes de que para calcular el área de un circulo no es la misma que el de un cuadrado, pero en vez de utilizar métodos diferentes podemos simplemente declarar un método llamado área y cambiar sus parámetros y comportamientos.
Este ejemplo codificado seria algo así en C#:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public abstract class Figura{ public abstract float CalcularArea(); } class circulo : Figura{ float radio; public override float CalcularArea() { return radio * (float)(Math.PI * Math.PI); } } class cuadrado : Figura { float lado; public override float CalcularArea() { return lado * lado; } } |
Como vemos utilizamos el mismo método que se hereda de la clase padre figura, y sus clases derivadas la implementan de diferentes formas.
En Java es algo como esto:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public abstract class figura { public abstract float area(); } class circulo extends figura{ float radio; @Override public float area() { return radio *(float)(Math.PI*Math.PI); } } class cuadrado extends figura{ float lado; @Override public float area() { return lado * lado; } } |
Utilizamos
@override
para implementar la clase abstracta y en este caso asignarle un comportamiento diferente.
Espero que con esto te hayan quedado un poco más claros estos pilares y en dado caso de que no, puedes visitar las referencias para comprender mejor.
- Fundamentos de Programación Orientada a Objetos: http://www.utn.edu.ec/reduca/programacion/poo/pilares.html