1 / 133

Extensión de clases

Extensión de clases. Introducción. El conjunto de métodos y campos accesibles desde el exterior de una clase, junto con la descripción de la forma en que se espera que esos miembros se comporten se denomina comúnmente el contrato de la clase.

chase
Download Presentation

Extensión de clases

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Extensión de clases

  2. Introducción • El conjunto de métodos y campos accesibles desde el exterior de una clase, junto con la descripción de la forma en que se espera que esos miembros se comporten se denomina comúnmente el contrato de la clase. • El contrato es lo que el diseñador de la clase ha prometido que la clase va a hacer

  3. Introducción • La extensión de clases proporciona dos formas de herencia: • Herencia de contrato o tipo, por la que una subclase adquiere el tipo de la superclase y se puede utilizar polimórficamente allí donde se pudiera utilizar la superclase. • Herencia de implementación, por lo que una subclase adquiere la implementación de la superclase en término de sus campos y métodos accesibles.

  4. Introducción • La extensión de clases puede usarse para múltiples propósitos. El más común es la especialización, donde la clase extendida define su nuevo comportamiento y por tanto se convierte en una versión especializada de su superclase.

  5. Introducción • La extensión de clases puede involucrar sólo el cambio de la implementación de un método heredado, quizá para hacerlo más eficiente. • Siempre que se extiende una clase, se crea una nueva clase con un contrato ampliado. • Sin embargo, no se cambia la parte del contrato que se hereda de la clase que se extiende

  6. Introducción • Cambiar la forma en la que se implementa el contrato de la superclase es razonable, pero nunca se debe hacerlo de forma en que se viole el contrato • La capacidad de extender clases está relacionada con los mecanismos de control de acceso para ampliar la noción del contrato que la clase presenta. Una clase puede presentar dos contratos diferentes: uno para los usuarios de la clase y otro para los extensores de la clase, ambos deben diseñarse cuidadosamente

  7. Introducción • Al extender una clase, la herencia de contrato y la herencia de implementación siempre se producen juntas. Sin embargo, pueden definirse nuevos tipos independientes de implementación usando interfaces. • Se pueden reutilizar implementaciones existentes, sin afectar al tipo, utilizando manualmente la composición y el reenvío.

  8. Una clase extendida • Como ejemplo se muestra una clase de atributos básica diseñada para almacenar parejas nombre-valor. Los nombres de los atributos son cadenas legibles como “color” o “posición” • Los valores de los atributos están determinadas por el tipo de atributo, por ejemplo, posición puede tener el valor de cadena de texto que represente la dirección de una calle, un conjunto de valores enteros representando longitud y latitud

  9. Una clase extendida publicclass Atrib { privatefinal String nombre; private Object valor=null; public Atrib (String nombre){ this.nombre=nombre; } public Atrib(String nombre, Object valor) { this.nombre = nombre; this.valor = valor; }

  10. Una clase extendida • Un atributo debe tener un nombre, de forma que cada constructor requiere una parámetro de nombre. • El nombre debe ser inmutable (y por tanto se marca como final) ya que puede usarse por ejemplo en una lista enlazada.

  11. Una clase extendida • Los atributos pueden tener cualquier tipo de valor por lo que dicho valor se almacena en una variable de tipo Object. • El valor puede cambiar en cualquier momento • Tanto nombre como valor son miembros private, por lo que puede accederse a ellos mediante los métodos apropiados. • Esto asegura que el contrato de Atrib se cumple siempre y da al diseñador de Atrib la libertad de cambiar en el futuro los detalles de la implementación sin afectar a los clientes de la clase

  12. Una clase extendida public String getNombre() { return nombre; } public Object getValor() { return valor; }

  13. Una clase extendida public Object setValor(Object nuevoValor){ Object valorAnt=valor; valor=nuevoValor; return valorAnt; } public String toString(){ return nombre + "='" + valor + “ "; } }

  14. Una clase extendida • Todas las clases vistas hasta ahora son clases extendidas, aunque no se declaren como tales. • Una clase como Atrib que no extiende explícitamente a otra clase, extiende implícitamente a Object. • Object está en la raíz de la jerarquía de clases y declara métodos que son implementados por todos los objetos, como toString • Las variables de tipo Object pueden referirse a cualquier objeto, sea éste una instancia de una clase o un array

  15. Una clase extendida • La siguiente clase extiende la noción de atributos de color, que podrían ser cadenas de texto para nombrar o describir colores. • Podría ser nombres como “crudo”, que podrían buscarse en una tabla o bien, valores numéricos que pueden decodificarse para producir una representación del color más eficiente que llamaremos ColorPantalla (que se supone definida en alguna otra parte)

  16. Una clase extendida • La decodificación de una descripción en un objeto ColorPantalla es lo suficientemente costosa como para desear realizarla una sola vez • Se extiende por tanto la clase Atrib creando una nueva clase AtribColor que tenga un método que obtenga un objeto ColorPantalla decodificado, implementado de tal forma que la decodificación se realice una sola vez

  17. Una clase extendida publicclass AtribColor extends Atrib{ private ColorPantalla miColor; //el color decodificado public AtribColor (String nombre, Object valor){ super(nombre, valor); decodifColor(); } public AtribColor(String nombre){ this(nombre, "transparente"); }

  18. Una clase extendida public AtribColor(String nombre, ColorPantalla valor){ super(nombre, valor.toString()); miColor=valor; } public Object setValor(ColorPantalla nuevoValor){ //sehaceque setValor delasuperclaseactúeprimero super.setValor(nuevoValor.toString()); ColorPantalla antValor= miColor; miColor= nuevoValor; return antValor; } public Object setValor(Object nuevoValor){ //se hace que setValor de la superclase actúe primero Object devValor=super.setValor(nuevoValor); decodifColor(); return devValor; }

  19. Una clase extendida //devuelve el objeto ColorPantalla decodificado public ColorPantalla getColor(){ return miColor; } //deun valor a ColorPantalla enfuncióndeladescripciónen getValor protectedvoid decodifColor(){ if(getValor()==null) miColor=null; else miColor=new ColorPantalla(getValor()); } }

  20. Object Atrib AtribColor Una clase extendida • AtribColor hace todo lo que hace Atrib y añade nuevo comportamiento

  21. Una clase extendida • La clase extendida AtribColor hace principalmente tres cosas: • Proporciona tres constructores: dos para reflejar los de su superclase y uno que acepta directamente un objeto ColorPantalla • Modifica y redefine el método setValor de su superclase, para que pueda establecer el objeto de color cuando se cambia el valor • Proporciona un nuevo método getColor que devuelve un valor que es la descripción del color decodificada en un objeto ColorPantalla

  22. Una clase extendida • Es interesante notar el uso del modificador de acceso protected en el método decodifColor, al marcarlo así puede accederse al mismo en la clase actual o, en una subclase pero, no es visible externamente

  23. Constructores en clases extendidas • Los objetos de las clases extendidas contienen variables de estado (campos) heredados de la superclase y campos definidos localmente en la clase. • Para construir un objeto de una clase extendida se deben inicializar correctamente ambos conjuntos de campos

  24. Constructores en clases extendidas • El constructor en una clase extendida puede tratar con campos locales pero sólo la superclase sabe cómo inicializar correctamente su estado, de forma que se cumpla su contrato. • Los constructores de clases extendidas deben delegar la construcción del estado heredado implícitamente o explícitamente invocando a un constructor de la superclase

  25. Constructores en clases extendidas • Un constructor de la clase extendida puede invocar directamente a uno de los constructores de la superclase usando otra clase de invocación explícita a un constructor: la invocación del constructor de la superclase, que usa la construcción super, Ej.: primer constructor de la clase AtribColor, al que se le pasa el nombre y el valor al correspondiente constructor de 2 argumentos de la superclase. Entonces se invoca a su propio método decodifColor para conseguir que miColor contenga una referencia al objeto ColorPantalla correcto

  26. Constructores en clases extendidas • Puede retrasarse la elección de qué constructor de la superclase va a utilizarse invocando explícitamente a uno de los constructores propios de la clase, usando this en vez de super, como se ve en el 2º constructor de AtribColor. Se asegura que cada atributo de color tiene un color, sino se proporciona un valor de color proporcionamos un valor por defecto de “transparente”.

  27. Constructores en clases extendidas • Sino se invoca al constructor de la superclase o a uno de nuestros propios constructores como primera sentencia ejecutable de nuestro propio constructor, se invoca automáticamente al constructor no-arg de la superclase antes de que se ejecute ninguna sentencia del nuevo constructor. Es decir, nuestro constructor se trata como si super() fuese su primera sentencia. Si la superclase no tiene un constructor no-arg, debe invocarse explícitamente a otro constructor.

  28. Constructores en clases extendidas • El 3º constructor de AtribColor permite al programador crear un nuevo objeto de tipo AtribColor para especificar al propio objeto ColorPantalla. Los 2 primeros constructores deben convertir sus parámetros a objetos ColorPantalla usando el método decodifColor, lo que posiblemente tiene un trabajo adicional. Cuando el programador tiene ya un objeto ColorPantalla para proporcionarle un valor, es conveniente evitar el trabajo adicional de esa conversión. Este es un ejemplo de cómo al proporcionar un constructor se aumenta la eficiencia, pero no se añaden capacidades nuevas.

  29. Constructores en clases extendidas • En este ejemplo AtribColor tiene constructores con las mismas signaturas que los constructores de la superclase. Esto no es en absoluto necesario, más aún es habitual. • Los constructores no son métodos y no se heredan

  30. Dependencias de ordenación de constructores • Cuando se crea un objeto, se reserva memoria para todos sus campos, incluyendo aquéllos que se heredan de su superclase. Estos campos se inicializan con valores que dependen de sus tipos respectivos (Ej.: 0 para valores numéricos, null para referencias a objetos)

  31. Dependencias de ordenación de constructores • Después, la construcción tiene 3 fases: • Se invoca al constructor de la superclase • Se inicializan los campos usando sus inicializadores y los bloques de inicialización • Se ejecuta el cuerpo del constructor • 1º se ejecuta la invocación implícita o explícita al constructor de la superclase.

  32. Dependencias de ordenación de constructores • Si se usa una invocación explícita a un constructor con this, se sigue la cadena de invocaciones hasta que se encuentra una invocación implícita o explícita a un constructor de la superclase, se invoca entonces al constructor de la superclase.

  33. Dependencias de ordenación de constructores • El constructor de la superclase se ejecuta usando las mismas 3 fases. Este procedimiento se aplica recursivamente, finalizándose cuando se alcanza el constructor de Object, ya que en este punto no existe ningún constructor de una superclase. Cualquier expresión evaluada como parte de la invocación explícita a un constructor no se puede referir a ningún miembro del objeto actual

  34. Dependencias de ordenación de constructores • En la segunda etapa todos los inicializadores de los campos y los bloques de inicialización se ejecutan en orden el que han sido declarados. En esta etapa se permiten referencias a otros miembros del objeto actual, suponiendo que hayan sido declarados

  35. Dependencias de ordenación de constructores • Finalmente, se ejecutan las sentencias reales del cuerpo del constructor. Si ese constructor se invocó explícitamente, tras la finalización de esas sentencias se devuelve el control al constructor que lo invocó y se ejecuta el resto de su cuerpo. Este proceso se repite hasta que se haya ejecutado el cuerpo del constructor especificado como parte de la construcción new

  36. Herencia y redefinición de miembros • Cuando se extiende una clase pueden añadirse miembros a dicha clase y también pueden redefinirse los existentes • El efecto exacto de redefinir un miembro heredado depende de la clase de miembro

  37. Redefinición • En la clase AtribColor se redefine y sobrecarga el método setValor • Sobrecargar un método significa proporcionar más de un método (en la misma clase) con el mismo nombre pero con diferente signatura, para distinguirlos

  38. Redefinición • Redefinir un método quiere decir sustituir la implementación del método de la superclase con uno propio. Las signaturas deben ser idénticas • Sobrecargar un método heredado quiere decir simplemente que hemos añadido un nuevo método con el mismo nombre que un método heredado pero con diferente signatura. Ej. setValor en AtribColor

  39. Redefinición • Redefinir un método significa que se sustituye su implementación, de forma que cuando se invoca al método sobre un objeto de la subclase, en realidad se invoca a la versión del método de la subclase. • En AtribColor redefinimos el método setValor(Object) de la clase Atrib proporcionando un nuevo método setValor(Object) que utiliza la palabra reservada super para invocar la implementación de la superclase y luego invoca a decodifColor. La referencia super se puede utilizar en invocaciones a métodos para acceder a métodos de la superclase que hayan sido redefinidos en la clase actual

  40. Redefinición • Cuando se redefinen métodos, la signatura y el tipo de retorno deben ser los mismos que en la superclase. Aunque dos métodos se diferencien sólo en el tipo de retorno, esto es un error y el compilador rechazará esta clase

  41. Redefinición • Los métodos que redefinen a otros poseen sus propios especificadores de acceso. Una subclase puede modificar el acceso a los métodos de la superclase, pero sólo para hacerlos más accesibles. Un método declarado protected en la superclase puede volverse a declarar de esta forma (lo usual) o se puede declarar public pero no puede declararse private ni tener acceso de paquete. Al hacer un método menos accesible que en la superclase se violaría el contrato de ésta, ya que una instancia de la subclase no podría utilizarse en lugar de una instancia de la superclase

  42. Redefinición • Los métodos que redefinen a otros pueden también cambiar los modificadores de los otros métodos. • Pueden ser final pero obviamente el que está siendo redefinido no • Un método de instancia no puede tener la misma signatura que un método estático heredado, ni viceversa. Sin embargo, un método redefinido se puede hacer abstract incluso aunque no lo fuera el método de la superclase

  43. Redefinición • En una subclase puede cambiarse el hecho que un parámetro de un método redefinido sea final, ya que el modificador final de un parámetro no es parte de la signatura del método, sino un detalle de la implementación

  44. Ocultación de campos • Los campos no pueden redefinirse, sólo pueden ocultarse. Si declaramos un campo en nuestra clase con el mismo nombre de un campo en la superclase, este otro existirá todavía, pero no podrá accederse directamente a él con su nombre simple. Debe usarse super u otra referencia del tipo de nuestra superclase para acceder a ese campo

  45. Acceso a miembros heredados • Cuando un método accede a un miembro de un objeto que se ha redefinido en una subclase, ¿a qué miembro se referirá el método?, ¿al de la superclase o al de la subclase?. La respuesta depende de la clase de miembro, de su accesibilidad y de cómo nos referimos a él

  46. Acceso a miembros heredados • Al invocar un método mediante una referencia de objeto, la clase real del objeto gobierna la implementación que se utiliza. Cuando se accede a un campo se utiliza el tipo declarado de la referencia.

  47. Acceso a miembros heredados publicclass SuperMostrar { public String cad="SuperCad"; publicvoid mostrar(){ System.out.println("Super.mostrar: "+ cad); } }

  48. Acceso a miembros heredados publicclass ExtendMostrar extends SuperMostrar{ public String cad= "ExtendCad"; publicvoid mostrar(){ System.out.println("Extend.mostrar: "+ cad); } publicstaticvoid main(String []args){ ExtendMostrar ext= new ExtendMostrar(); SuperMostrar sup= ext; sup.mostrar(); ext.mostrar(); System.out.println("sup.cad= "+sup.cad); System.out.println("ext.cad= "+ext.cad); } }

  49. Acceso a miembros heredados • Sólo hay un objeto, pero tenemos dos variables que contienen referencias al mismo. Una variable tiene tipo SuperMostrar (la superclase) y la otra tiene tipo ExtendMostrar (la clase real). • Veamos la salida del programa cuando se ejecuta

  50. Acceso a miembros heredados Extend.mostrar: ExtendCad Extend.mostrar: ExtendCad sup.cad= SuperCad ext.cad= ExtendCad

More Related