8:Interfaces y Clases Internas - jferrert/Programacio/PiensaEnJava/8 - Interfaces... ...

download 8:Interfaces y Clases Internas - jferrert/Programacio/PiensaEnJava/8 - Interfaces...  8:Interfaces

of 50

  • date post

    21-Sep-2018
  • Category

    Documents

  • view

    216
  • download

    0

Embed Size (px)

Transcript of 8:Interfaces y Clases Internas - jferrert/Programacio/PiensaEnJava/8 - Interfaces... ...

  • 8:Interfaces y Clases Internas Interfaces y clases internas proporcionan formas ms sofisticadas para organizar y controlar los objetos en tu sistema.

    C++, por ejemplo, no contiene estos mecanismos, aunque un programador inteligente puede simularlos. El hecho de que existan en Java indica que son considerados lo bastante importantes como para proporcionar apoyo directo mediante palabras clave del lenguaje.

    En el Captulo 7 , aprendiste sobre la palabra clave abstract , la cual te permite crear uno o ms mtodos en una clase sin tener definiciones - t proporcionas parte del interfaz sin proporcionar una implementacin correspondiente, la cual es creada por los herederos. La palabra clave interface produce completamente una clase abstracta, la cual no proporciona implementacin a todo. Aprenders que la interface es ms que slo una clase abstracta llevada a un extremo, ya que te permite realizar una variacin sobre la "herencia mltiple" de C++, creando una clase que puede ser upcast a ms de un tipo base.

    Al principio, las clases internas parecen un mecanismo simple de ocultacin de cdigo: t colocas clases dentro de otras clases. Aprenders, sin embargo, que la clase interna hace ms que eso - conoce y se puede comunicar con la clase circundante - y que el tipo de cdigo que puedes escribir con clases internas es ms elegante y claro, aunque sea un nuevo concepto para muchos. Lleva algo de tiempo el sentirse cmodo con el diseo usando clases internas.

    Interfaces

    La palabra reservada interface lleva el concepto abstract un paso ms all. Podras pensar en ello como una clase abstract "pura". Esto permite al creador establecer la forma de una clase: nombres de mtodos, listas de argumentos, y tipos de devolucin, pero no los cuerpos de los mtodos. Un interface puede contener campos, pero stos son implcitamente static y final . Un interfaceproporciona slo una forma, no una implementacin.

    Un interface dice: "As es como parecern todas las clases que implementen este interface en particular."

    Aunque cualquier cdigo que use un interface en particular sabe qu mtodos podran ser llamados por ese interface , y eso es todo. As que el interface se usa para establecer un "protocolo" entre clases. (Algunos lenguajes de programacin orientados a objetos tienen una palabra clave llamada protocol que

  • hace lo mismo.)

    Para crear un interface , utilice la palabra clave interface en lugar de la palabra clave class . Como en una clase, puedes aadir la palabra reservada publicantes de la palabra clave interface (pero slo si ese interface est definido en un fichero del mismo nombre) o no ponerle nada para darle un estado "amigo" de forma que slo se pueda usar dentro del mismo paquete.

    Para hacer una clase que se ajuste a un interface particular (o grupo de interfaces ) utilice la palabra reservada implements . Ests diciendo "Elinterface es lo que parece, pero ahora voy a decir cmo trabaja ."Ms que eso, parece herencia. El diagrama para mostrar un ejemplo es:

    Una vez que has implementado un interface , esa implementacin se convierte en una clase ordinaria que puede ser extendida de forma regular.

    Puedes elegir declarar de forma explcita las declaraciones de mtodos en un interface como public . Pero son public incluso si no lo indicas. De esta manera cuando implementas un interface , los mtodos del interface deben ser definidos public . De otra manera seran por defecto "amigos", y estaras reduciendo la accesibilidad de un mtodo durante la herencia, lo cual no es permitido por el compilador de Java.

    Puedes ver esto en la versin modificada del ejemplo Instrument . Advierte que

  • cada mtodo en el interface es extrictamente una declaracin, lo cual es lo nico que el compilador permite. En suma, ninguno de los mtodos en Instrument son declarados como public , pero son public automticamente de todas maneras:

    //: c08:music5:Music5.java // Interfaces. import java.util.*; interface Instrument { // Constante en tiempo de compilacin: int i = 5; // static & final // No puedes tener definiciones de mtodos: void play(); // Automaticamemte pblico String what(); void adjust(); } class Wind implements Instrument { public void play() { System.out.println("Wind.play()"); } public String what() { return "Wind"; } public void adjust() {} } class Percussion implements Instrument { public void play() { System.out.println("Percussion.play()"); } public String what() { return "Percussion"; } public void adjust() {} } class Stringed implements Instrument { public void play() { System.out.println("Stringed.play()"); } public String what() { return "Stringed"; } public void adjust() {} } class Brass extends Wind { public void play() { System.out.println("Brass.play()"); } public void adjust() { System.out.println("Brass.adjust()"); }

  • } class Woodwind extends Wind { public void play() { System.out.println("Woodwind.play()"); } public String what() { return "Woodwind"; } } public class Music5 { // No te preocupes del tipo, porque los // nuevos tipos son aadidos al sistema // todava funcionan correctamente: static void tune(Instrument i) { // ... i.play(); } static void tuneAll(Instrument[] e) { for(int i = 0; i

  • porque hay veces que necesitas decir "Un x es un a y un b y un c ". En C++, este hecho de combinar mltiples interfaces de clases es llamado herencia mltiple , y aporta bastante equipaje incmodo porque cada clase puede tener una implementacin. En Java, puedes aportar el mismo mecanismo, pero slo una de las clases pueden tener una implementacin, de forma que los problemas de C++ no ocurren con Java cuando combines varios interfaces:

    En una clase derivada, no ests obligado a tener una clase base que sea tanto una clase abstracta o "concreta" (una sin mtodos abstract ). Si no heredas de un interface , pudes heredar slo de uno. El resto de elementos base deben serInterfaces . Colocas todos los nombres de interfaces tras la palabra reservadaimplements y separadas por comas. Puedes tener tantos interfaces como quieras-cada uno ser un tipo diferente para lanzar hacia arriba. El siguiente ejemplo muestra una clase concreta combinada con varios interfaces para producir una nueva clase:

    //: c08:Adventure.java // Multiple interfaces. import java.util.*; interface CanFight { void fight(); } interface CanSwim { void swim(); } interface CanFly { void fly(); } class ActionCharacter {

  • public void fight() {} } class Hero extends ActionCharacter implements CanFight, CanSwim, CanFly { public void swim() {} public void fly() {} } public class Adventure { static void t(CanFight x) { x.fight(); } static void u(CanSwim x) { x.swim(); } static void v(CanFly x) { x.fly(); } static void w(ActionCharacter x) { x.fight(); } public static void main(String[] args) { Hero h = new Hero(); t(h); // Treat it as a CanFight u(h); // Treat it as a CanSwim v(h); // Treat it as a CanFly w(h); // Treat it as an ActionCharacter } } ///:~

    Puedes ver que Hero combina la clase concreta ActionCharacter con los interfaces CanFight, CanSwim, y CanFly . Cuando combinas una clase concreta con interfaces de esta manera, la clase concreta debe aparecer primero, despus los interfaces. (El compilador da un error si no lo haces as.)

    Advierte que la signatura para fight() es la misma en el interface CanFicht y en la clase ActionCharacter , y que fight() no viene con una definicion en Hero . La regla para un interface es que puedes heredar de el (como veras pronto), pero entonces tendras otro interface . Si quieres crear un objeto del nuevo tipo, debe ser una clase que proporcione todas las definiciones. Incluso aunque Hero no proporciona explicitamente una definicion de fight() , la definicin viene ms adelante con ActionCharacter aunque es automticamente proporcionada y es posible crear objetos de Hero .

    En la clase Adventure , puedes ver que hay cuatro metodos que toman como argumentos los distintos interfaces y la clase concreta. Cuando un objeto Hero es creado, puede ser pasado a cualquiera de estos metodos, lo cual significa que esta siendo upcast a cada interface en turno. Debido a la forma en que los interfaces son diseados en Java, funciona sin impedimento y sin ningun esfuerzo en particular por parte del programador.

    No olvides que la razon principal de los interfaces esta mostrada en el ejemplo anterior: ser capaz de upcast a mas de un tipo tipo base. Sin embargo, una segunda razon para usar interfaces es lo mismo que usar una clase base abstracta : evitar al programador cliente hacer un objeto de esta clase y

  • establecer que es solo un interface. Esto trae una cuestion: Debes usar un interface o una clase abstracta ? Un interface te da los beneficios de una clase abstracta y los beneficios de un interface , luego es posible si quieres crear tu clase base sin ninguna definicion de metodos o variables miembro usar interfaces a clases abstractas . De hecho, si sabes que algo va a ser una clase base, la primera eleccion sera hacer un interface , y solo si estas forzado a tener definiciones de metodos o variables miembro cambiarias aun a clase abstracta , o si es necesario a una clase concreta.

    Colisiones de nombres al combinar interfaces

    Puedes encontrarte con un pequeo problema cuando implementas multiples interfaces. En el ejemplo anterior, tanto CanFight como ActionCharacter tienen un metodo identico, void fight() . Esto no es un problema porque el mtodo sea identico en ambos casos, pero y si no lo es? Aqui tienes un ejemplo:

    //: c08: InterfaceCollision.java interface I1 { void f(); } interface I2 { int f(int i); } interface I3 { int f(); } class C { public int f() { return 1; } } class C" implement