En1. Clase y objeto Objeto es una entidad que posee características y comportamiento. Unidad de información que conoce datos y sabe como procesarlos Unidad de información compuesta por atributos y metodos // objeto.nombre = "Gus"; objeto.procesar(); //invocar metodo o mensaje El estado de un objeto es la combinación de los valores que toman los atributos de un objeto objeto.contador = 2; objeto.contador = 5; Orientación a objetos es la técnica de programación para construir software utilizando el concepto de objeto. Una clase define los atributos y comportamiento comunes que comparte un tipo de objetos . Una clase es un molde de un objeto. class Pila { T [] arreglo; int i; int numeroElementos; void push(T elemento){ arreglo[++i] = elemento;} T pop(){ i--; return arreglo[i+1];} } Los atributos son las caracteristicas visibles de una clase. pila.push("hola"); pila.numeroElementos; pila.pop(); El comportamiento de un objeto, es la acción que realiza cuando un cliente le invoca un metodo o un atributo. Un mensaje es la invocación que se puede realizar sobre un objeto. Un mensaje puede cambiar al estado de un objeto Un objeto es la instancia o ejemplar de una clase Pila stack; stack = new Pila(); //instanciar Constructor es un método que se utiliza para inicializar objetos cuando son instanciados. class Pila { Pila() {//constructor por omision arreglo = null; i=-1; numeroElementos=-1; } Pila(int capacidad ){ arreglo = new T[capacidad];i=-1; numeroElementos=-1; } } ... stack1= new Pila(); stack2= new Pila(10); 2. Encapsulamiento. Relación cliente-proveedor. Un cliente de una clase es un segmento de código que utiliza a un objeto de una clase determinada, y al cual le envia mensajes Un proveedor de una clase es quien codifica a los metodos de la misma. La relación cliente-proveedor consiste en la manera como una clase invoca un objeto. Siempre una clases el cliente de un objeto, y siempre un objeto es proveedor de metodos. Un cliente se comunica con un proveedor por medio de mensajes. Un codigo estrechamente ligado (fuertemente acoplado) es aquel que depende de la implantación de la clase. Clase proveedor encapsulada public class Proveedor { private int valor; public int incrementar(){ valor++; return valor; } public int decrementar() { valor--; return valor; } public int getPropiedad() { return valor; } public void setPropiedad(int elValor){ if (elValor>0) valor = elValor; } } Clase cliente que usa encapsulamiento import junit.framework.TestCase; public class TestProveedor extends TestCase{ //cliente de clase proveedor private Proveedor elProveedor; public void setUp() { elProveedor = new Proveedor(); } public void testIncrementar() { elProveedor.setPropiedad(10); assertEquals(11,elProveedor.incrementar()); assertEquals(11,elProveedor.getPropiedad()); assertEquals(10,elProveedor.decrementar()); } public void testDecrementar() { assertEquals(-1,elProveedor.decrementar()); assertEquals(0,elProveedor.incrementar()); } } A todas aquellas operaciones publicas de una clase se le denomina el contrato de la clase. A todas aquellas operaciones y atributos privados de una clase se le denomina la implantación de la clase Normalmente el contrato de la clase se debe expresar como un conjunto de capacidades (o poderes) que puede tener un objeto. Entre objetos existen relaciones, para poder realizar sus metodos. La relación tiene-un (HAS-A), consiste en que un objeto se asocia con otro objeto para ejecutar un metodo Delegacion, consiste en que un objeto que tiene una relación de tipo tiene-un con otro objeto, reutiliza a este ultimo, para la ejecución de metodos. Por ejemplo, la clase Pelicula va a ser utilizada por el Cine, para que este ultimo delege el trabajo, durante el metodo exhibir de la clase Cine. public class Pelicula { private String nombre; private int duracion;//en minutos private String genero; public Pelicula(String elNombre) { nombre = elNombre;} public void contarHistoria() { System.out.println(nombre + ":"+duracion+" minutos:"+genero ); } public String getNombre() { return nombre;} public int getDuracion() { return duracion;} public void setDuracion(int laDuracion){ duracion=laDuracion;} public String getGenero() { return genero;} public void setGenero(String elGenero) { genero=elGenero;} } public class Cine { private Pelicula pelicula; private String nombre; private int capacidad; public Cine(String elNombre) { nombre = elNombre;} public void exhibir() { pelicula.contarHistoria();//delegacion } public Pelicula getPelicula() { return pelicula;} public void setPelicula(Pelicula laPelicula) { pelicula = laPelicula;} public String getNombre() { return nombre;} public int getCapacidad() { return capacidad;} public void setCapacidad(int laCapacidad) { capacidad = laCapacidad;} } Observar que la relación entre ambos objetos se pone al momento de ejecutar al programa import junit.framework.TestCase; public class CineTest extends TestCase { private Cine elCine; public void setUp() { elCine = new Cine("Savoy"); } public void testExhibir() { Pelicula laPelicula = new Pelicula("El retorno del rey"); laPelicula.setGenero("Fantasia"); laPelicula.setDuracion(210); elCine.setPelicula(laPelicula); assertEquals(laPelicula,elCine.getPelicula()); elCine.exhibir(); Pelicula otraPelicula= new Pelicula("Las dos torres"); otraPelicula.setGenero("Fantasia"); otraPelicula.setDuracion(190); elCine.setPelicula(otraPelicula); elCine.exhibir(); } } 3. Herencia La herencia es un mecanismo que permite basar una clase nueva a partir de la definición de una clase existente. A través de la herencia, la clase hereda todos los atributos y comportamientos (atributos y metodos publicos) de la clase ancestro. public class Ancestro { public void x() ; } public class Descendiente extends Ancestro { public void y() { x(); } } La herencia permite reutilizar atributos y métodos, pero a diferencia de la delegación, tambien reutiliza al tipo de dato del Ancestro. La herencia introduce un nuevo tipo de relación entre objetos, que es la relación ES-UN (IS-A) En Java, toda clase tiene un ancestro raiz, que es la clase Object (java.lang.Object) Una jerarquia de herencia es un mapa de relaciones "ES-UN", y es un arbol que se da entre clases, como resultado de la herencia. Redefinir es el proceso mediante el cual una clase hija toma un metodo de la clase ancestro y lo reescribe con el propósito de cambiar su comportamiento. La herencia se debe aplicar si y solo si la clase pasa la prueba "Es un", que consiste en verificar si la clase lógicamente se relaciona con el ancestro. Ejemplo: Horno extiende a una Cocina? No, una cocina tiene a un horno Guitarra extienda a un Instrumento Musical ? Si Persona extiende a un Empleado ? No, se debe cambiar por Empleado extiende Persona Ferrari extiende a un Motor ? No, un Ferrari tiene un motor Ferrari extienda a un Coche? Si PinkFloyd extiende BandaRock ? Si Cerveza extiende a Bebida ? Si Martini extiende a Bebida ? Si Martini extiende a Cerveza ? No Pila extiende a una Lista Ligada?No LibroGUI extiende a un Libro? No Tipos de herencia Herencia para reautilizar la implementación Consiste en tomar el codigo del ancestro y definir la nueva clase a partir de lo mismo, pero sin agregar o redefinir nuevos metodos public class ListaLigada { public void agregar(T elemento) .... public void borrar(T elemento) .... public T recuperar(String llave) ... public void inserterEnMedio(T elemento) ... } public class Pila extends ListaLigada { } NO CREAR TIPOS DE DATOS (CLASES) FICTICIAS. Herencia por diferencia. Consiste en heredar una clases y agregarle solamente el código que la haga distinta de la clase de la cual se está heredando. La especialización es el proceso mediante el cual una clase se define a sí misma en términos de los aspectos que la hacen diferente de su clase ancestro. La especialización consiste en agregar nuevos metodos o redefinir métodos public class Circulo { private double radio; public Circulo() { radio=0.0;} public Circulo(double elRadio) { radio=elRadio;} public getRadio() { return radio;} public double perimetro() { return 2*Math.PI*radio;} public double area() { return Math.PI*radio*radio;} } public class Esfera extends Circulo { public Esfera() { super(); } public Esfera(double elRadio) { super(elRadio); } public double perimetro() { return -1.0;} public double volumen() { return 4*Math.PI*radio*radio*radio/3; } } Una clase es abstracta cuando contiene métodos o atributos definidos, pero algunos de ellos se necesitan declarar pero aun no especificar. Dichos metodos se califican como abstract; y por tanto la clase debe ser abstract. Una clase abstracta no puede tener instancias public abstract class Figura { protected double radio; public double getRadio() { return radio;} public abstract double perimetro(); public abstract double area(); } Las clases abstractas normalmente se colocan en la raíz de la jerarquia de herencia y permiten ir modelando parcialmente el comportamiento de un componente del sistema, posponiendo la especificación final de las clases descendientes. Una clase "hoja" de una jerarquía de herencia, es aquella que se declara de tal manera que ya no pueden existir descendientes. En el caso de Java, una clase calificada como final, es convertida en una clase hoja. En el caso de Java, toda clase desciende de java.lang.Object Herencia por sustitución Una clase realiza herencia por sustitución cuando debe empotrarse o adaptarse a un sistema ya existente. import java.applet.Applet; import java.awt.Graphics; public class MiApplet extends Applet { public void paint(Graphics g) { g.drawOval(50,50,50,40); } }

Ejemplo de Applet

En Java, la herencia múltiple NO está permitida La herencia múltiple consiste en definir a una clase por medio de dos o más clases ancestro import java.applet.Applet public class CirculoApplet extends Applet , Circulo { ..... } 3. Polimorfismo. Polimorfismo, que significa "muchas formas", permite que un solo nombre de clase o metodo represente a diferente código. La selección del código a ejecutar cuando se usa polimorfismo, es utilizando un mecanismo automático de la programación orientada a objetos, llamado ligadura dinámica (dynamic binding) Una variable o referencia polimorfica es aquella que puede contener muchos tipos distintos. Existen varios tipos de polimorfismo Polimorfismo de inclusión. Permite dar un tratamiento generico a objetos relacionados por herencia. El polimorfismo de inclusión se lograr tipicamente, definiendo una clase abstracta en la jerarquia public abstract class Personalidad { private String estadoAnimo; protected final String getEstadoAnimo() { return estadoAnimo; } protected final void setEstadoAnimo(String elEstado) { estadoAnimo=elEstado; } public abstract void actuar() ; } Y se definen clases especificas que son descendientes de la clase abstracta public class Optimista extends Personalidad { public Optimista() { setEstadoAnimo("riendo"); } public void actuar() { System.out.println("Optimista " +getEstadoAnimo()); } } public class Pesimista extends Personalidad { public Pesimista() { setEstadoAnimo("llorando"); } public void actuar() { System.out.println("Pesimista " +getEstadoAnimo()); } } Lo que permite el polimorfismo de inclusión es manipular genericamente a objetos que tienen en común a una clase, por medio de herencia public class Psicologo { /* public void analizarPesimista(Pesimista persona ) { persona.actuar(); } public void analizarOptimista(Optimista persona ) { persona.actuar(); } public void analizar(Pesimista persona ) { persona.actuar(); } public void analizar(Optimista persona ) { persona.actuar(); } */ public void analizar(Personalidad persona) { persona.actuar(); } } El polimorfismo de inclusión evita escribir casos particulares por cada clase que se presente en el sistema. import junit.framework.TestCase; public class PsicologoTest extends TestCase { private Psicologo elPsicologo; protected void setUp() { elPsicologo= new Psicologo(); } public void testAnalizar() { Personalidad [] personalidades={ new Optimista(), new Pesimista()}; for (int i=0;i