Anda di halaman 1dari 27

Java Programming Tutorial

POO - Herencia y polimorfismo


1. Composicin
Hay dos maneras de reutilizar las clases existentes, a saber, la composicin y la herencia. Con la composicin (o agregacin ), se crea una nueva clase, que se compone de clases existentes. Con la herencia , se crea una nueva clase, que est basada en una clase existente, con algunas modificaciones o ampliaciones.

Como ejemplo de la reutilizacin de una clase a travs de la composicin, supongamos que tenemos una existente clase llamada Point , que se define como se muestra: El cdigo fuente para Point.java es la siguiente:
1public class Point { 2 private int x, y; 3 Point pblico (int x, int y) { 4 this.x = x; 5 this.y = y; 6 } 7 Punto pblico () { 8 x = 0; 9 y = 0; 10 } 11 pblico getX int () { 12 return x; 13 } 14 public void setX (int x) { 15 this.x = x; 16 } 17 getY public int () { 18 regresar y; 19 } / / (x, y) coordina / / constructor

/ / constructor no-arg

20 21 22 23 24 25 26}

setY public void (int y) { this.y = y; } public String toString () { return "(" + x + "," + y + ")"; }

Supongamos que necesitamos una nueva clase llamada Lnea , se puede volver a utilizar el Punto de clase a travs de la composicin .Decimos que "una lnea se compone de dos puntos", o "una lnea con dos puntos". Composicin exhibe a "tiene una" relacin. UML notacin: En notacin UML, la composicin se representa como una lnea de diamantes cabeza apuntando a sus mandantes. El cdigo fuente para Line.java es la siguiente:
1public class Line { 2 Punto inicial, final; / / puntos inicial y final 3 de lnea pblica (int x1, int y1, int x2, int y2) { 4 empezar = new Point (x1, y1); 5 final = new Point (x2, y2); 6 } 7 Lnea pblico (punto de comenzar, terminar Point) { 8 this.begin = comenzar; 9 this.end = fin; 10 } 11 public String toString () { 12 volver "Lnea de" + empezar + "a" + fin; 13 } 14}

/ / constructor 1

/ / constructor 2

Una clase piloto de pruebas: TestLine.java


1TestLine clase pblica { 2 public static void main (String [] args) { 3 Punto p1 = nuevo punto (1, 2); 4 System.out.println (p1); 5 Punto p2 = nuevo punto (3, 4); 6 System.out.println (p2); 7 8 Lnea line1 = new Line (p1, p2); 9 System.out.println (lnea 1); 10 11 Lnea line2 = new Line (0, 0, 1, 1); 12 System.out.println (lnea 2); 13 }

14} (1,2) (3,4) Lnea de (1,2) a (3,4) Lnea de (0,0) a (1,1)

2. Herencia
En programacin orientada a objetos, a menudo organizan clases de jerarqua para evitar la duplicacin y reducir la redundancia . Las clases de la jerarqua inferior heredan todas las variables (atributos estticos) y mtodos (comportamiento dinmico) de las jerarquas ms altas. Una clase en la jerarqua inferior se llama una subclase (o derivado , nio , clase extendida ). Una clase en la jerarqua superior se llama una superclase (o de base , clase padre ). Al extraer todas las variables y mtodos comunes en las superclases, y dejar las variables y mtodos especializados en las subclases, la redundancia se puede reducir considerablemente o eliminarse ya que estas variables comunes y mtodos no necesita ser repetido en todas las subclases. Por ejemplo,

Una subclase hereda todas las variables y los mtodos de sus superclases, como su padre inmediato, as como todos los antepasados. Es importante sealar que una subclase no es un "subconjunto" de una superclase. En contraste, la subclase es un "superconjunto" de una superclase. Es debido a una subclase hereda todas las variables y mtodos de la superclase y, adems, se extiende la superclase proporcionando ms variables y mtodos. En Java, debe definir una subclase usando la palabra clave " se extiende ", por ejemplo,
Portero clase extiende SoccerPlayer {...} MyApplet clase extiende java.applet.Applet {...} Cilindro clase extiende Circle {...}

UML Notacin: La notacin UML para la herencia es una lnea continua con una punta de
flecha hueca que lleva de la subclase a la superclase, como se muestra:

2.1 Un Ejemplo de Herencia

En este ejemplo, se deriva una subclase llamada Cilindro de la superclase Circle , que hemos creado en el captulo anterior. Es importante tener en cuenta que reutilizar la clase Circle . De reutilizacin es una de las propiedades ms importantes de la POO. (Por qu reinventar las ruedas?) La clase cilindro hereda todas las variables miembro ( radio y de color ) y mtodos ( getRadius () , getArea () , entre otros) de su superclase Circle . Adems, define una variable llamada altura , dos mtodos pblicos - getHeight () y getVolume () y sus propios constructores, como se muestra:
1public class Cilindro extiende Circle { 2 altura doble privada; / / variable miembro 3 4 Cilindro pblico () { / / constructor una 5 super (); / / invocar superclase 'Circle constructor ()

6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22}

height = 1,0; } Cilindro pblico (radio doble, doble altura) { / / Constructor 2 super (radio); / / invocar superclase 'Circle constructor (radio) this.height height =; } getHeight public double () { volver altura; } setHeight public void (doble altura) { this.height height =; } public double getVolume () { volver getArea () * altura; getArea / / Usar Circle () }

No se puede ejecutar el cilindro clase, ya que no es una independiente programa (no hay main () del mtodo). La clase del cilindro est destinado a ser utilizado en otros programas. Tenemos que escribir otra clase llamada " TestCylinder "para probar el Cilindro de clase de la siguiente manera:
1public class TestCylinder { 2 public static void main (String [] args) { 3 Cilindro Cilindro CY1 = new (); / / constructor uso 1 4 System.out.println ("El radio es" + cy1.getRadius () 5 + "La altura es" cy1.getHeight + () 6 + "El color es" + cy1.getColor () 7 + "Base de apoyo es" + cy1.getArea () 8 + "El volumen es" + cy1.getVolume ()); 9 10 Cilindro cy2 = new cilindro (5,0, 2,0); / / constructor uso 2 11 System.out.println ("El radio es" + cy2.getRadius () 12 + "La altura es" cy2.getHeight + () 13 + "El color es" + cy2.getColor () 14 + "Base de apoyo es" + cy2.getArea () 15 + "El volumen es" + cy2.getVolume ()); 16 } 17}

Mantener el " Cylinder.java "y" TestCylinder.java "en el mismo directorio que" Circle.class "(ya que estamos reutilizando la clase Circle ). Compilar y ejecutar el programa. El resultado esperado es el siguiente:
El radio es 1,0 Altura 1.0 Color se est rea Base roja 3.141592653589793 3.141592653589793 volumen es El radio es 5,0 altura es de 2,0 Color est rea Base roja 78.53981633974483 volumen es 157,07963267948966

2,2 reemplazo de mtodos y variables Hiding

Una subclase hereda todas las variables miembro y mtodos de sus superclases (el padre inmediato y todos sus antepasados). Se pueden utilizar los mtodos heredados y variables como son. Tambin puede sustituir un mtodo heredado aportando su propia versin, u ocultar una variable heredada definiendo una variable del mismo nombre. Por ejemplo, el mtodo heredado getArea () en un cilindro objeto calcula el rea de la base del cilindro. Supongamos que decide anular el getArea () para calcular el rea de la superficie del cilindro en la clase del cilindro . A continuacin se presentan los cambios:
1public class Cilindro extiende Circle { 2 ...... 3 / / Sobrescribir el getArea () mtodo heredado de la superclase Circle 4 pblico getArea doble () { 5 retorno de 2 * Math.PI getRadius * () * altura + 2 * super.getArea (); 6 } 7 / / Es necesario cambiar el getVolume (), as 8 public double getVolume () { 9 volver super.getArea () * altura; / / usar getArea superclase '() 10 } 11 / / Sobrescribir el toString () heredado 12 public String toString () { 13 volver "Cilindro: radio =" + getRadius () + "height =" + altura; 14 } 15}

Si getArea () se llama desde un crculo de objeto, se calcula el rea del crculo. Si getArea () se llama desde un cilindro objeto, se calcula el rea de la superficie del cilindro mediante la aplicacin se reemplaza . Tenga en cuenta que usted tiene que utilizar mtodo de acceso pblico getRadius () para recuperar el radio del crculo , ya que el radio se declara privada y por lo tanto no se puede acceder a otras clases, incluyendo la subclase Cilindro . Pero si se ha sobrepasado la getArea () en el cilindro , el getVolume () ( = getArea () * altura ) ya no funciona. Es porque se reemplaza la getArea () se utiliza en cilindro , que no calcule la superficie de base. Puede solucionar este problema mediante el uso super.getArea () , para utilizar la versin de la superclase de getArea () . Tenga en cuenta que super.getArea () slo puede emitirse desde la definicin de subclase, pero no de una instancia creada, por ejemplo c1.super.getArea () , ya que romper el ocultamiento de informacin y el principio de encapsulacin.

2,3 Palabra clave " sper "


Recordemos que dentro de una definicin de clase, puede utilizar la palabra clave esta para referirse a esta clase . De manera similar, la palabra clave sper refiere a la superclase, que podra ser el precursor inmediato o su antepasado. La palabra clave sper permite acceder a la subclase "mtodos y variables dentro de la subclase 'superclase definicin. Por ejemplo, super () y super ( argumentList ) se puede utilizar invocar el constructor de la superclase. Si la subclase sobreescribe un mtodo heredado de su superclase, dice getArea () , puede utilizar super.getArea () para invocar la versin de

superclase 'dentro de la definicin de subclase. Del mismo modo, si la subclase oculta una variable de superclase, puede utilizar super. variableName para hacer referencia a la variable oculta dentro de la definicin de subclase.

2.4 Ms acerca de Constructores


Recordemos que la subclase hereda todas las variables y los mtodos de sus superclases. Sin embargo, la subclase no hereda los constructores de sus superclases. Cada clase en Java define sus propios constructores. En el cuerpo de un constructor, puede utilizar super ( args ) para invocar un constructor de su superclase inmediata. Tenga en cuenta que super ( args ) , si se utiliza, debe ser la primera instruccinen el constructor de la subclase. Si ella no se utiliza en el constructor, el compilador Java de insertar automticamente un super () declaracin para invocar el constructor no-arg de su superclase inmediata.Esto se deduce del hecho de que el padre tiene que nacer antes de que el nio pueda nacer. Es necesario construir correctamente las superclases antes de poder construir la subclase.

2,5 predeterminado constructor no-arg


Si no hay ningn constructor se define en una clase, el compilador Java de crear automticamente un sin argumentos (no-arg) constructor , que simplemente emite un super () llamada, de la siguiente manera:
/ / Si no se define en el constructor de un compilador inserta clase, este constructor no-arg pblica ClassName () { super (); / / llamar la "superclase no-arg constructor }

Tome en cuenta que: El valor por defecto no-arg constructor no se generar automticamente, si uno (o ms) se defini constructor. En otras palabras, es necesario definir no-arg constructor explcitamente si otros constructores se han definido. Si la superclase inmediata no tiene el constructor por defecto (que define algunos constructores, pero no define un constructor sin argumentos), obtendr un error de compilacin en hacer un super ()llamada. Tenga en cuenta que Java compilador inserta una super () como la primera instruccin de un constructor si no hay super (args) .

2,6 herencia simple

Java no soporta herencia mltiple (C + + hace). La herencia mltiple permite una subclase de tener ms de un superclases directas. Esto tiene un serio inconveniente si las superclases tienen aplicacin en conflicto para el mismo mtodo. En Java, cada subclase puede tener una y slo una superclase directa, es decir, la herencia simple. Por otro lado, una superclase puede tener muchas subclases.

2.7 Clase raz comn - java.lang.Object


Java adopta un denominado comn-raz enfoque. Todas las clases de Java se derivan de una clase raz comn llamado java.lang.Object . Este objeto clase define e implementa

los comportamientos comunes que se requieren de todos los objetos Java que se ejecutan en el marco del JRE. Estos comportamientos comunes de permitir la aplicacin de caractersticas tales como el multithreading y recolector de basura.

2,8 Otro ejemplo sobre Sucesiones

Supongamos que se nos exige a los estudiantes y maestros modelo en nuestra aplicacin. Podemos definir una superclase denominada Person para almacenar las propiedades comunes, tales como nombre ydireccin , y las subclases de Student y Teacher por sus propiedades especficas. Para los estudiantes, tenemos que mantener las asignaturas cursadas y sus calificaciones respectivas, aadir un curso de grado, imprimir todas las asignaturas cursadas y la calificacin promedio. Un estudiante no toma ms de 30 cursos para todo el programa. Para los maestros, tenemos que mantener los cursos que se imparten en la actualidad, y capaces de agregar o quitar un curso impartido. Un maestro no ensea ms de 5 cursos al mismo tiempo. Diseamos las clases de la siguiente manera:
/ / Superclase public class Persona {

/ / las variables de instancia private String nombre; direccin de la cadena privada; / / Constructor Persona pblico (String nombre, direccin String) { this.name = nombre; this.address = direccin; } / / Getters public String getName () { devolver el nombre; } getAddress public String () { la direccin del remitente; } public String toString () { devolver el nombre + "(" + direccin + ")"; } } public class Estudiante extiende Persona { / / las variables de instancia numCourses int privado; / / nmero de cursos realizados hasta el momento, max 30 private String [] cursos; / / Curso cdigos privados int [] calidades, / / grado para los cdigos de los cursos correspondientes privadas estticas MAX_COURSES final int = 30; / / mximo nmero de cursos / / Constructor Estudiante pblico (String nombre, direccin String) { super (nombre, direccin); numCourses = 0; cursos = new String [MAX_COURSES]; grados = new int [MAX_COURSES]; } @ Override public String toString () { volver "Estudiante:" + super.toString (); } / / Aadir un curso y su grado - No hay validacin de este mtodo addCourseGrade public void (curso String, int grado) { cursos [numCourses] = curso; calificaciones [numCourses] = grado; numCourses + +; }

/ / Imprimir todos los cursos tomados y su grado printGrades public void () { System.out.print (this); for (int i = 0; i <numCourses, i + +) { System.out.print ("" + cursos [i] + ":" + calificaciones [i]); } System.out.println (); } / / Clculo de la nota media getAverageGrade public double () { int suma = 0; for (int i = 0; i <numCourses, i + +) { suma + = calificaciones [i]; } volver (dobles) suma / numCourses; } } public class Profesor extiende Persona { / / las variables de instancia numCourses int privado; / / nmero de cursos que se imparten en la actualidad private String [] cursos, cdigos / / cursos privados MAX_COURSES estticas final int = 10; / / Cursos mximos / / Constructor Maestro pblica (String nombre, direccin String) { super (nombre, direccin); numCourses = 0; cursos = new String [MAX_COURSES]; } @ Override public String toString () { return "Maestro:" super.toString + (); } / / Devuelve falso si el curso duplicado que se aadirn addCourse pblica booleano (curso String) { / / Comprobar si el curso ya est en la lista de cursos for (int i = 0; i <numCourses, i + +) { si (cursos [i] es igual a (por supuesto).) return false; } cursos [numCourses] = curso; numCourses + +; return true; } / / Devuelve falso si el curso no lo hace en la lista de cursos

removeCourse pblica booleano (curso String) { / / Buscar el ndice del curso int = courseIndex numCourses; for (int i = 0; i <numCourses, i + +) { if (campos [i]. equals (por supuesto)) { courseIndex = i; break; } } si (== courseIndex numCourses) { / / No se puede encontrar el curso que se elimin return false; } else { / / eliminar el rumbo y volver a organizar los cursos-array for (int i = courseIndex; i <numCourses-1; i + +) { cursos [i] = cursos [i +1]; } numCourses -; return true; } } } public class Prueba { public static void main (String [] args) { / / Prueba de clase Estudiante Estudiante s1 = new Estudiante ("Tan Teck Ah", "1 Happy Ave"); s1.addCourseGrade ("IM101", 97); s1.addCourseGrade ("IM102", 68); s1.printGrades (); System.out.println ("La media es" + s1.getAverageGrade ()); / / Prueba de clase Maestro Teacher Teacher t1 = nuevo ("Paul Tan", "8 vas de extincin"); System.out.println (t1); String [] = {cursos "IM101", "IM102", "IM101"}; para (curso de cuerdas: cursos) { if (t1.addCourse (curso)) { System.out.println (curso + ", agreg."); } Else { System.out.println (curso + "no se puede aadir."); } } para (curso de cuerdas: cursos) { if (t1.removeCourse (curso)) { System.out.println (curso + "quitado."); } Else { System.out.println (curso + "no se puede quitar."); } } } }

Estudiante: Tan Teck Ah (1 Feliz Ave) IM101: 97 IM102: 68 Promedio es de 82,5 Maestro: Paul Tan (8 manera puesta del sol) IM101 aadido. IM102 aadido. IM101 no se puede aadir. IM101 eliminado. IM102 eliminado. IM101 no se puede quitar.

2,9 de anotacin @ Override (JDK 1.5)


La " @ Override "se conoce como anotacin (introducido en JDK 1.5), que pide compilador para comprobar si existe tal mtodo en la superclase a ser anulado. Esto ayuda mucho si usted escribe incorrectamente el nombre del mtodo a ser anulado. Por ejemplo, suponga que desea reemplazar el mtodo toString () en una subclase. Si @ Override no se utiliza y toString () es incorrecta comotoString () , ser tratado como un nuevo mtodo en la subclase, en lugar de anular la superclase. Si @ Override se utiliza, el compilador indicar un error. @ Override anotacin es opcional, pero sin duda agradable de tener.

2,10 Ejercicio sobre Sucesiones


ENLACE A LOS EJERCICIOS

3. Composicin vs Herencia
Recordemos que hay dos maneras de reutilizar las clases existentes: composicin y herencia . Hemos visto que una lnea de clase se puede implementar utilizando composicin de Punto de clase - "una lnea est compuesta de dos puntos". Una lnea tambin se puede implementar, utilizar la herencia, desde el punto de clase - "una lnea es un punto de ampliarse en un punto" - de la siguiente manera:

1public class Lnea extiende Point { 2 / / La herencia del punto inicial de la superclase 3 final Point; / / fin Point 4 Line pblico (x1 int, int y1, int x2, int y2) { / / constructor una 5 super (x1, y1) / / llamar al constructor de la superclase para construir el punto ini 6 final = new Point (x2, y2); 7 } 8 Lnea pblico (punto de comenzar, terminar Point) { / / constructor 2 9 super (begin.getX (), begin.getY ()); / / llamar al constructor de la superclase para 10 this.end = fin; 11 } 12 public String toString () { 13 volver "Lnea de" super.toString + () + "a" + fin; 14 } 15}

Estudiar las dos versiones de la clase Line. Supongo que es ms fcil de decir que "la lnea est compuesta por dos puntos" que "una lnea es un punto de ampliarse en un punto". Regla de oro: composicin uso si es posible, antes de considerar la herencia.

3.1 Ejercicios
ENLACE A LOS EJERCICIOS DE COMPOSICIN VS HERENCIA

4. Polimorfismo
La palabra " polimorfismo "significa" muchas formas ". Viene del griego " poly "(significa muchos ) y " morfos "(medios formulario ). Para obtener ejemplos, en qumica, carbono muestra un polimorfismo debido a que se pueden encontrar en ms de una forma: grafito y el diamante. Cada una de la forma tiene su propio distintas propiedades.

4,1 sustituibilidad

Una subclase posee todos los atributos y operaciones de su superclase (debido a una subclase hereda todos los atributos y operaciones de su superclase). Esto significa que un objeto subclase puede hacer lo que su superclase puede hacer. Como resultado, podemos sustituir una instancia de la subclase cuando una instancia de la superclase que se espera, y todo lo que se trabajar muy bien. Esto se conoce como sustitucin . En nuestro ejemplo anterior del Crculo y del cilindro : Cilindro es una subclase del Crculo . Podemos decir que el cilindro " es-un "crculo (en realidad, " es-ms-queun " crculo ). Subclase-superclase exhibe una llamada " es-una "relacin. Via sustitucin , podemos crear una instancia de cilindro , y asignarlo a un crculo (su superclase) de referencia, como sigue:
/ / Sustituir una instancia de la subclase a la superclase su referencia Circle aCircle = new cilindro (5,0);

Puede invocar todos los mtodos definidos en el Crculo de clase para la referencia aCircle , (que esen realidad la celebracin de un cilindro deobjeto), por ejemplo aCircle.getRadius

() y aCircle.getColor () . Esto se debe a una instancia de la subclase posee todas las

propiedades de su superclase. Sin embargo, no se puede invocar mtodos definidos en el Cilindro de clase para la referencia aCircle , por ejemplo aCircle.getHeight () yaCircle.getVolume () . Esto es porque aCircle es una referencia a la Circle clase, que no sabe acerca de los mtodos definidos en la subclasecilindro . aCircle es una referencia a la Circle clase, pero contiene un objeto de la subclase del cilindro . La referencia aCircle , sin embargo, retiene su identidad interna . En nuestro ejemplo, la subclase Cilindro anula mtodos getArea () y toString () . aCircle.getArea
() o aCircle.toString () invoca la reemplaza versin definida en la subclase del cilindro ,

en lugar de la versin definida en crculo . Esto se debe a aCircle es, de hecho, la celebracin de un cilindro objeto internamente.

4,2 upcasting y downcasting

Upcasting una instancia de subclase a una referencia Superclase


Sustituyendo una instancia de la subclase a la superclase se llama " upcasting ". Esto se debe a que, en un diagrama de clases UML, subclase es a menudo drwan por debajo de su superclase. Upcasting essiempre seguro porque una instancia de la subclase posee todas las propiedades de su superclase y puede hacer lo que su superclase puede hacer. El compilador comprueba upcasting vlida y errores cuestiones "tipos incompatibles" en caso contrario. Por ejemplo,
Crculo c1 = Cilindro nuevo (); . control / / compilador para asegurarse de que el valor R es una subclase de la L-valor crculo C2 = new String (); / / Recopilacin de error: tipos incompatibles

Downcasting una referencia sustituido a su clase original


Se puede volver una referencia sustituido de nuevo a la subclase original. Esto se llama " downcasting ". Por ejemplo,
Ciclo aCircle = new cilindro (5,0); aCircle aCylinder Cilindro = (cilindro); operador / / upcast es seguro / necesidades / abatidos el casting

Downcasting requiere de tipo explcita operador de fundicin en forma de operador de prefijo ( nuevo tipo ) . Downcasting no siempre es seguro, y arroja un tiempo de ejecucin ClassCastExceptionsi la instancia que se va downcasted no pertenece a la subclase correcta. Un objeto subclase puede ser sustituido por su superclase, pero lo contrario no siempre es cierto. Compilador puede no ser capaz de detectar el error en la conversin explcita, que slo se detectar en tiempo de ejecucin. Por ejemplo,
Crculo c1 = new Circle (5); Objeto o1 = new Object (); c1 = o1; / / error de compilacin: tipos incompatibles

c1 = (Circle) o1, error / / Ejecucin: java.lang.ClassCastException: El objeto no se puede convertir al Crculo

4.3 El " instanceof "Operador


Java proporciona un operador binario llamado instanceof que devuelve verdadero si un objeto es una instancia de una clase particular. La sintaxis es la siguiente:
unObjeto instanceof AClass Crculo c1 = new Circle (); System.out.println (c1 instanceof Circulo); if (c1 instanceof Cirlce) {...... }

/ / true

Una instancia de la subclase es tambin una instancia de su superclase. Por ejemplo,


Crculo c1 = new Circle (5); Cilindro CY1 = new cilindro (5, 2); System.out.println (c1 instanceof Circulo); / / true System.out.println (c1 instanceof cilindro); / / false System.out.println (CY1 instanceof cilindro); / / true System.out.println (CY1 instanceof Circle); / / true Crculo c2 = new cilindro (5, 2); System.out.println (c2 instanceof Circulo); System.out.println (c2 instanceof cilindro);

/ / true / / true

4,4 Resumen de polimorfismo


1. Una instancia de la subclase procesa todas las operaciones de los atributos de su superclase. Cuando una instancia de la superclase se espera, que puede ser sustituido por una instancia de la subclase. En otras palabras, una referencia a una clase puede contener una instancia de esa clase o una instancia de una de sus subclases - se llama sustitucin. 2. Si una instancia de la subclase es asignar a una referencia superclase, puede invocar los mtodos definidos en la superclase solamente. No se puede invocar mtodos definidos en la subclase. 3. Sin embargo, la instancia sustituido conserva su propia identidad en trminos de mtodos sobrescritos y variables escondites. Si la subclase sobreescribe los mtodos de la superclase, la versin de la subclase, se ejecutar, en lugar de la versin de la superclase.

4.5 Ejemplo de polimorfismo


El polimorfismo es muy potente en la programacin orientada a objetos para separar la interfaz y la implementacin con el fin de permitir que el programador programa en la interfaz en el diseo de unsistema complejo .

Consideremos el siguiente ejemplo. Supongamos que nuestro programa usa muchos tipos de formas, tales como tringulos, rectngulos, etc. Debemos disear una superclase denominada Shape , que define la interfaz pblica (o comportamientos) de todas las formas. Por ejemplo, nos gustara que todas las formas de tener un mtodo llamado getArea () , que devuelve el rea de esa forma particular. La Forma clase se puede escribir como sigue.
public class Shape { / / variable de instancia Color private String; / / Constructor Forma pblico (color String) { this.color = color; } public String toString () { volver "Shape of color = \" "+ color +" \ ""; } / / Todas las formas debern tiene un mtodo llamado getArea () pblico getArea doble () { System.err.println ("Shape desconocido no se puede calcular area!"); return 0; / / Necesidad de un retorno a compilar el programa } }

Tome en cuenta que tenemos un problema en la escritura de la getArea () mtodo en la forma de clases, ya que la zona no puede ser calculado a menos que la forma real es desconocida. Vamos a mostrar un mensaje de error por el momento. En la ltima seccin, voy a mostrar cmo resolver este problema.

continuacin,

puede

derivar

subclases,

como Tringulo y Rectangle ,

de

la

superclase Shape .
public class Rectangle ampla Shape { / / Instancia de las variables longitud int privado; Ancho int privado; / / Constructor Rectngulo pblico (color String, int longitud, anchura int) { super (color); this.length = longitud; this.width = ancho; } @ Override public String toString () { volver "Rectngulo de longitud =" + longitud + "y width =" + ancho + ", subclase de" super.toString + (); } @ Override pblico getArea doble () { volver largo ancho *; } } public class Tringulo ampla Shape { / / Instancia de las variables base int privado; altura int privado; / / Constructor Tringulo pblico (color String, base de int, int altura) { super (color); this.base = base; this.height height =; } @ Override public String toString () { return "Tringulo de la base =" + base + "y height =" + altura + ", subclase de" + super.toString (); } @ Override pblico getArea doble () { retorno 0.5 * base * altura; } }

Las subclases anular el getArea () mtodo heredado de la superclase, y proporcionar las implementaciones adecuadas para getArea () . En nuestra aplicacin, podemos crear referencias de Forma y asignarles las instancias de subclases, a saber:
public class TestShape { public static void main (String [] args) { Forma s1 = new Rectangle ("rojo", 4, 5); System.out.println (s1); System.out.println ("El rea es" + s1.getArea ()); Forma s2 = new Triangulo ("azul", 4, 5); System.out.println (s2); System.out.println ("El rea es" + s2.getArea ()); } }

La belleza de este cdigo es que todas las referencias son de la superclase (es decir, la programacin a nivel de interfaz ). Se podra crear una instancia instancia subclase diferente, y el cdigo funciona todava. Se podra ampliar su programa fcilmente mediante la adicin de ms subclases, como el Crculo , cuadrado , etc, con facilidad. Sin embargo, la definicin anterior de Shape clase plantea un problema, si alguien instancias de un Shape objeto e invocar el getArea () de la Forma objeto, el programa se interrumpe.
public class TestShape { public static void main (String [] args) { / / Construir una instancia de Shape plantea problema! Forma s3 = new Shape ("verde"); System.out.println (s3); System.out.println ("El rea es" + s3.getArea ()); } }

Esto es porque la Forma clase est destinado a proporcionar una interfaz comn a todas sus subclases, que se supone que proporcionan la aplicacin real. No queremos a nadie a instancias de una forma de instancia. Este problema se puede resolver mediante el uso de la denominada extracto clase.

5. Clases abstractas e Interfaces


5.1 El resumen Mtodo
Un resumen es un mtodo con la firma nica (es decir, el nombre del mtodo, la lista de argumentos y el tipo de retorno) sin la aplicacin (es decir, el cuerpo del mtodo). Se utiliza la palabra clave abstractpara declarar un resumen del mtodo. Por ejemplo, en la forma de clase, podemos declarar tres abstracto mtodos getArea () , draw () , como sigue:
pblico abstracto doble getArea (); pblico abstracto empate vaco ();

La aplicacin de estos mtodos no es posible en la forma de clases, como la forma real no se conoce todava. (Cmo calcular el rea si la forma no es conocido?) Aplicacin de estos abstractos mtodos se proporciona ms adelante una vez que la forma real es desconocida. Estas abstractas mtodos no pueden ser invocadas por no tener aplicacin.

5.2 El resumen de Clase

Una clase que contiene uno o ms abstractas mtodos se llama un extracto clase. Un resumen de la clase se debe declarar con un modificador de clase abstracta . Vamos a reescribir nuestra forma de clases como un resumen de la clase, que contiene un resumen mtodo getArea () de la siguiente manera:
pblico abstracto clase Shape { / / variable de instancia Color private String; / / Constructor Forma pblico (color String) { this.color = color; } public String toString () { volver "Shape of color = \" "+ color +" \ ""; } / / Todas las subclases de Shape debe implementar un mtodo llamado getArea () public abstract double getArea (); }

Un resumen

de la

clase

es incompleto en

su

definicin,

ya

que

la

aplicacin

de

sus abstractos mtodos falta. Por lo tanto, un resumen de la clase no puede ser instanciada . En otras palabras, no se pueden crear instancias de un resumen de la clase (de lo contrario, tendr una instancia incompleta con cuerpo de mtodo no encontrado). Para usar un extracto de clases, usted tiene que obtener una subclase de la abstraccin de clases. En la subclase derivada, hay que anular las abstractas y mtodos de asegurar la aplicacin a todos losabstractos mtodos. La subclase derivada se ha completado, y se pueden crear instancias. (Si una subclase no proporciona la aplicacin a todos los abstractos mtodos de la superclase, la subclase sigue siendo abstracto .) Esta propiedad de la abstraccin clase resuelve nuestro problema antes. En otras palabras, puede crear instancias de las subclases como Tringulo y rectangular , y upcast a Shape (a fin de programar y operar a nivel de interfaz), pero no se puede crear una instancia de Shape , que evitar el peligro de que tenemos enfrentado. Por ejemplo,
public class TestShape { public static void main (String [] args) { Forma s1 = new Rectangle ("rojo", 4, 5); System.out.println (s1); System.out.println ("El rea es" + s1.getArea ()); Forma s2 = new Triangulo ("azul", 4, 5); System.out.println (s2); System.out.println ("El rea es" + s2.getArea ()); / / No se puede crear una instancia de una clase abstracta Shape s3 = new Shape ("verde"); Error / / Recopilacin! } }

En resumen, un resumen de clase proporciona una plantilla para un mayor desarrollo . El propsito de una clase abstracta es proporcionar una interfaz comn (o protocolo o contrato, o acuerdo, o convenio de denominacin) a todas sus subclases. Por ejemplo, en el resumen de la clase Shape , puede definir mtodos abstractos como getArea () y draw () . No aplicacin es posible porque la forma real no se conoce. Sin embargo, mediante la especificacin de la firma de los abstractos mtodos, todas las subclases estn obligados a utilizar estos mtodos de firma. Las subclases podra proporcionar las implementaciones adecuadas. Junto con el polimorfismo, puede upcast instancias de subclases de Shape , y en el programa Forma nivel, i, e., el programa en la interfaz. La separacin de la interfaz y la implementacin permite un mejor diseo de software, y la facilidad en expansin. Por ejemplo, Shape define un mtodo llamado getArea () , que todas las subclases deben proporcionar la correcta aplicacin. Puede solicitar una getArea ()de las subclases de Shape, el rea correcta ser calculada. Adems, la aplicacin se puede ampliar fcilmente para adaptarse a las nuevas formas (como Crculo o cuadrado ) derivando ms subclases.

Regla de oro: en la interfaz del programa, no en la ejecucin. (Es decir, hacen referencia a la
superclase; sustituto con instancias de subclases, y llamar a los mtodos definidos en la superclase solamente.) Notas: Un mtodo abstracto no puede ser declarada definitiva , como ltimo mtodo no se puede reemplazar. Un extracto mtodo, por otro lado, debe reemplazarse en un descendiente antes de que pueda ser utilizado. Un resumen mtodo no puede ser privado (que genera un error de compilacin). Esto se debe privado mtodo no son visibles para la subclase y por lo tanto no se puede reemplazar.

5,3 El interfaz

Un Java interface es una superclase abstracta del 100% , que define un conjunto de mtodos de sus subclases deben soportar. Unainterfaz slo contiene pblicas mtodos abstractos (mtodos con la firma y la aplicacin no) y, posiblemente, las constantes ( pblicasestticas finales variables). Usted tiene que usar la palabra clave " interface "para definir una interfaz (en lugar de la palabra clave "clase "para las clases normales). La palabra clave pblica y abstracto no son necesarios para los mtodos abstractos como son obligatorios. Una interfaz es un contrato por lo que las clases pueden hacer. Es, sin embargo, no especifica cmo las clases debe hacerlo. Interfaz de convencin de nomenclatura: Utilice un adjetivo (por lo general terminaba con " poder ") que consiste en una o ms palabras.Cada palabra ser mayscula

inicial

(camel-case). Por

ejemplo, Serializable , Extenalizable , muebles , clonable , Ejecutable , etc Por ejemplo, supongamos que nuestra aplicacin incluye muchos objetos que pueden moverse. Podramos definir una interfaz llamada mvil , que contiene las firmas de los mtodos de movimiento diferentes.
public interface mviles { / / mtodos abstractos para ser implementadas por las subclases moveUp public void (); moveDown public void (); moveLeft public void (); moveRight public void (); }

Al igual que un resumen de la clase, una interfaz no puede ser instanciada, porque es incompleta (cuerpo de los mtodos abstractos "que falta). Para utilizar una interfaz, una vez ms, debe derivar subclases y dar aplicacin a todos los mtodos abstractos declarados en la interfaz. Las subclases se han completado y se pueden crear instancias. Para derivar subclases de una interfaz , un nuevo teclado " implementa "es para ser utilizado en lugar de" extends "para derivar subclases de una clase ordinaria o un extracto clase. Es importante sealar que la aplicacin de una interfaz subclase necesita reemplazar todos los mtodos abstractos definidos en la interfaz, de lo contrario, la subclase no puede ser compilado. Por ejemplo,
public class MovablePoint implementa mviles { variables / / Instancia - (x, y) las coordenadas del punto private int x; private int y; / / Constructor pblico MovablePoint (int x, int y) { this.x = x; this.y = y; } public String toString () { return "Punto en (" + x + "," + y + ")"; } / / Aplicar mtodos abstractos definidos en la interfaz mvil @ Override moveUp public void () { y -; } @ Override moveDown public void () { y + +; }

@ Override moveLeft public void () { x -; } @ Override moveRight public void () { x + +; } }

Otras clases de la aplicacin de manera similar puede implementar el mvil interfaz y proporcionar su propia implementacin de los abstractos mtodos definidos en la interfaz mvil . Tambin puede upcast casos subclase a la movible de la interfaz, a travs de polimorfismo, similar a un extracto clase.
public class TestMovable { public static void main (String [] args) { Muebles m1 = new MovablePoint (5, 5); / / upcast System.out.println (m1); m1.moveDown (); System.out.println (m1); m1.moveRight (); System.out.println (m1); } }

5.4 Aplicacin Mltiple interfaz s


Como se ha mencionado, Java slo soporta herencia simple . Es decir, una subclase se pueden derivar de una y slo superclase. Java no soporta herencia mltiple para evitar heredar propiedades en conflicto de las superclases mltiples. La herencia mltiple, sin embargo, tiene su lugar en la programacin. Una subclase, sin embargo, se puede aplicar ms de una interfaces. Esto se permite en Java como una interfaz que define nicamente los mtodos abstractos sin las implementaciones reales y menos probables conduce a heredar propiedades en conflicto de varias interfaces. En otras palabras, Java apoya indirectamente herencias mltiples a travs de la aplicacin de mltiples interfaces. Por ejemplo,
public class Circle ampla Shape implementa mvil, visualizable superclase pero implementar mltiples interfaces ....... } { / / Un

5,5

interfaz Sintaxis Formal


interfaceName

La sintaxis para la declaracin formal de la interfaz es la siguiente:


[ pblico | protegida | paquete ] interfaz

[ extiende superInterfaceName ] { / / Constantes static final ...; Firma mtodos / / abstractos " ... }

Todos los mtodos en una interfaz debe ser pblica y abstracta (por defecto). Usted no puede utilizar otro modificador de acceso como privado , protegido y por defecto, o modificadores tales comoesttico , definitivo . Todos los campos deben ser pblicas , esttico y definitivo (por defecto). Una interfaz puede " se extiende "desde una interfaz sper. UML Notacin: La notacin UML utiliza una flecha de lnea continua que une la subclase de una superclase concreta o abstracta, y se lanz la lnea de flecha a una interfaz como se muestra. Clase abstracta y mtodo abstracto se muestran en cursiva.

5.6 Por qu interfaz s?


Una interfaz es un contrato (o un protocolo, o una comprensin comn) de lo que las clases pueden hacer. Cuando una clase implementa una interfaz determinada, se compromete a proporcionar la aplicacin a todos los mtodos abstractos declarados en la interfaz. Interfaz define un conjunto de comportamientos comunes. Las clases implementan la interfaz de acuerdo con estos comportamientos y proporcionar su propia implementacin de los comportamientos. Esto le permite programar en la interfaz, en lugar de la aplicacin real. Uno de el uso principal de interfaz es proporcionar un contrato de comunicacin entre dos objetos. Si conoces a una clase implementa una interfaz, entonces usted sabe que clase contiene implementaciones concretas de los mtodos declarados en la interfaz, y usted est garantizado para poder invocar estos mtodos de forma segura. En otras palabras, dos objetos

pueden comunicarse basndose en el contrato definido en la interfaz, en lugar de su aplicacin especfica. En segundo lugar, Java no soporta herencia mltiple (mientras que C + + hace). La herencia mltiple que permite derivar una subclase de ms de una superclase directa. Esto plantea un problema si dos superclases directas tienen implementaciones en conflicto. (Lo que hay que seguir en la subclase?). Sin embargo, la herencia mltiple tiene su lugar. Java hace esto al permitir que "realiza" ms de una interfaces (pero slo se puede "se extiende" desde una sola superclase). Desde interfaces contienen slo mtodos abstractos sin aplicacin real, no hay conflicto puede surgir entre los mltiples interfaces. (Interfaz puede contener constantes, pero no es recomendable. Si una subclase implementa dos interfaces con constantes conflictos, el compilador marcar un error de compilacin.)

5.7 Ejercicios
ENLACE A LOS EJERCICIOS DE polimorfismo, clases abstractas e interfaces

5,8 (Late Binding) Dynamic Binding


A menudo el tratamiento de un objeto no como su propio tipo, pero como su tipo base (superclase o interfaz). Esto le permite escribir cdigos que no depende de un tipo de aplicacin especfica. En el Shapeejemplo, siempre podemos utilizar getArea () y no tienen que preocuparse si son tringulos o crculos. Esto, sin embargo, plantea un nuevo problema. El compilador no puede saber en tiempo de compilacin con precisin qu pedazo de cdigo que va a ser ejecutado en tiempo de ejecucin (por ejemplo,getArea () cuenta con una implementacin diferente para rectngulo y tringulo ). En el lenguaje de procedimientos como C, el compilador genera una llamada a un nombre de funcin especfica, y el editor de enlaces resuelve esta llamada a la direccin absoluta del cdigo que se ejecuta en tiempo de ejecucin. Este mecanismo se denomina enlace esttico (o enlace anticipado ). Para apoyar el polimorfismo, lenguaje orientado a objetos utiliza un mecanismo diferente llamado enlace dinmico (o en tiempo de ejecucin o en tiempo de ejecucin obligatoria ). Cuando se invoca un mtodo, el cdigo a ser ejecutado slo se determina en tiempo de ejecucin. Durante la compilacin, el compilador comprueba si el mtodo existe y funciona tipo comprobar en los argumentos y el tipo de cambio, pero no sabe qu pieza de cdigo que se ejecutar en tiempo de ejecucin. Cuando se enva un mensaje a un objeto para invocar un mtodo, el objeto se da cuenta de que el pedazo de cdigo que se ejecutar en tiempo de ejecucin. Aunque el enlace dinmico se resuelve el problema en el apoyo polimorfismo, se plantea otro problema nuevo. El compilador no puede comprobar si el operador de conversin de tipo es seguro. Slo se puede comprobar en tiempo de ejecucin (lo que arroja un ClassCastException si falla la comprobacin de tipos). JDK 1.5 introduce una nueva caracterstica llamada genricos para hacer frente a este problema. Vamos a discutir este problema y los genricos en detalle en el captulo posterior.

6. Object-Oriented Design Issues


6,1 Encapsulacin, Acoplamiento y Cohesin
En Diseo OO, es deseable disear las clases que se bien encapsuladas, dbilmente acoplados y altamente cohesiva, de manera que las clases son fciles de mantener y adecuado para su reutilizacin. La encapsulacin se refiere a mantener los datos y el mtodo dentro de una clase de dichos usuarios no tienen acceso a los datos directamente, sino a travs de las pblicas mtodos. encapsulacin estrictaque se desea, lo cual puede lograrse mediante la declaracin toda la variable privada , y la disponibilidad pblica getter y setter para las variables . La ventaja es que tiene el control completo de cmo los datos se va a leer (por ejemplo, en la forma de formato) y cmo los datos se va a cambiar (por ejemplo, la validacin). [TODO] Ejemplo: Clase Tiempo con horas variables privadas (0-23), los minutos (0-59) y el segundo (0-59); getters y setters (arroja IllegalArgumentException ). El tiempo interno tambin podra almacenarse como el nmero de segundos desde la medianoche para facilidad de operacin (Hidding informacin). Hidding informacin: Otro beneficio clave de encapsulacin estricta es Hidding informacin, lo que significa que los usuarios no son conscientes (y no necesitan ser conscientes) de cmo los datos se almacenan internamente. El beneficio de la encapsulacin estricta-out pesos la sobrecarga necesaria en las llamadas a mtodos adicionales. C oupling se refiere al grado en el que una clase se basa en el conocimiento de los componentes internos de otra clase. Acoplamiento fuerte no es deseable porque si una clase cambia sus representaciones internas, todas las otras clases estrechamente acoplado necesitan ser reescritos. [TODO] Ejemplo: Una clase utiliza el tiempo y depende de la hora variables, minuto y segundo. Claramente, el acoplamiento flexible se asocia a menudo con encapsulacin estricta. Por ejemplo, bien definida, mtodo pblico para acceder a los datos, en lugar de acceder directamente a los datos. C ohersion se refiere al grado en el que se resiste a ser una clase o mtodo roto en pedazos ms pequeos. Alto grado de cohesin es deseable. Cada clase estar diseado para modelar una sola entidad, con su conjunto bien definido de responsabilidades y llevar a cabo un conjunto de tareas estrechamente relacionadas, y cada mtodo debe cumplir una sola tarea. Clases bajas cohersion son difciles de mantener y reutilizar. [TODO] Ejemplo de cohersion bajo: Libro y el Autor en una clase, o Car and Driver en una clase. Una vez ms, cohersion alto est asociado con acoplamiento dbil. Esto se debe a una clase altamente cohesivo tiene menos (o mnima) interacciones con otras clases.

6,2 "es-un" frente "tiene-un" relaciones


"Es una" relacin: Un objeto subclase procesa todos los datos y los mtodos de su superclase (y podra haber ms). Podemos decir que un objeto de la subclase es-un objeto superclase (es algo ms que un objeto de la superclase). Consulte la seccin "polimorfismo".

"Tiene una" relacin: En la composicin, una clase contiene referencias a otras clases, que se conoce como "tiene-un". Usted puede utilizar el "es-un" y "tiene-a" para comprobar si el diseo de las clases mediante herencia o composicin.

6.3 Programa en la interfaz, no a la aplicacin


Consulte el polimorfismo