0% encontró este documento útil (0 votos)
3 vistas53 páginas

Jerarquía de Herencia y Métodos Abstractos

El documento describe la jerarquía de herencia en programación orientada a objetos utilizando clases abstractas y métodos abstractos, como en el caso de la clase Shape y sus subclases. Se enfatiza la importancia del polimorfismo, permitiendo que diferentes formas se manejen a través de una referencia común y se implementen métodos como 'getArea' y 'draw'. Además, se introduce el concepto de interfaces, que permiten a las clases implementar múltiples comportamientos sin herencia múltiple, facilitando la separación de preocupaciones en el diseño del software.

Cargado por

digranada8
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
3 vistas53 páginas

Jerarquía de Herencia y Métodos Abstractos

El documento describe la jerarquía de herencia en programación orientada a objetos utilizando clases abstractas y métodos abstractos, como en el caso de la clase Shape y sus subclases. Se enfatiza la importancia del polimorfismo, permitiendo que diferentes formas se manejen a través de una referencia común y se implementen métodos como 'getArea' y 'draw'. Además, se introduce el concepto de interfaces, que permiten a las clases implementar múltiples comportamientos sin herencia múltiple, facilitando la separación de preocupaciones en el diseño del software.

Cargado por

digranada8
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd

8.

3 An Inheritance Hierarchy Using 1


Abstraction

Circle

getArea() : double
draw(Graphics)

Higo. 8.9 El Círculo clase con “ obtenerArea ” y " dibujar " métodos agregado

Un obvio problema aquí es eso a Forma no puedo calcular es área, o dibujar en


sí, así que qué implementación quería nosotros poner en este ¿clase? En casos
como este, dónde No existe una implementación significativa para el método de la
superclase, podemos usar métodos abstractos. Un método abstracto, además de
estar etiquetado con la palabra clave “ abstract ” , no tiene cuerpo de método; la
firma simplemente termina con un punto y coma:

Nota
De a diseño perspectiva, este mezclando arriba de subyacente objeto
comportamiento y representación visual es no a bien separación de
preocupaciones. Él es usado en este ejemplo justo facilitar la ilustración visual de
los resultados de varios componentes del código.
Una clase que contiene uno o más métodos abstractos debe marcarse como “
abstracta ” , ya que sin un conjunto completo de implementaciones de métodos no
se puede crear una instancia de ella. Esto también obliga a todas las subclases a
implementar los métodos abstractos, o también deben marcarse como abstractas.
Figura 8.10 muestra a Más grande herencia jerarquía de abstracto y concreto
formas. En Lenguaje de programación unificada, un abstracto clase o método
poder ser indicado por usando itálico texto, como poder se puede ver en la clase
Shape y sus métodos “ getArea ” y “ draw ” . La forma unidimensional y Forma
bidimensional clases son también abstracto y no tengo para anular el “ getArea ”
heredado y “ dibujar ” métodos. Sin embargo, todas las clases concretas en la
parte inferior de la jerarquía deben proporcionar implementaciones de estos
métodos.
Aquí se muestra la implementación completa de la clase abstracta Shape.
Observe los métodos abstractos “ getArea ” y “ draw ” , agregados desde la
versión anterior de la clase.
8.4 Dynamic Binding and Abstract 201
Methods

Forma
ubicación : Punto
dimensiones :
entero[]
obtenerArea ( ) :
doble
dibujar( Gráficos)

OneDimensionalShape TwoDimensionalShape
getDimension() : int getHeight() : int
getWidth() : int
Cuadrado Círculo
obtenerArea ( ) : obtenerArea ( ) :
doble doble
sorteo(Gráficos) sorteo(Gráficos)

Oval Rectangle RightAngledTriangle


getArea() : getArea() : double getArea() : double
double draw(Graphics) draw(Graphics)
draw(Graphics)

RoundedRectangle
arcwidth
archeight
getArea() :
double
draw(Graphics)
Higo. 8.10 El completo Forma jerarquía
202 8 Inheritance, Polymorphism and
Interfaces

Las demás clases abstractas permanecen sin cambios. Todas las clases
concretas anularán los métodos “ getArea ” y “ draw ” . El siguiente ejemplo es
una versión actualizada de la clase Circle. La clase Math es útil aquí en el método
“ getArea ” . abastecimiento ambos el valor de PI, y el “ ¡Pow ! ” método cual
aumenta el primer parámetro valor a el fuerza de el segundo. El " dibujar "
método Sorteos a lleno ovalado (hay un “ drawOval ” similar) método que
dibuja un óvalo sin relleno). Tenga en cuenta que este método es igualmente capaz
de dibujar un círculo y un óvalo. El objeto Graphics que se pasa como parámetro
se pasará al método desde un componente gráfico.
8.4 Dynamic Binding and Abstract 203
Methods

A diferencia de Circle, que es una subclase de OneDimensionalShape , la clase


Oval hereda de FormaBidimensional . Nota cómo el implementación de es Los
métodos utilizan los métodos “ getHeight ” y “ getWidth ” de la superclase.
204 8 Inheritance, Polymorphism and
Interfaces
El actualizado Rectángulo, también, es a Forma bidimensional , entonces
también usos el
“ obtenerAncho ” y “ obtenerAltura ” heredado métodos a calcular es área y
dibujar sí mismo.

El Rectángulo redondeado clase es a subclase de Rectángulo (es decir a


concreto subclase de una superclase concreta) pero agrega una campo para
representar el radio de la esquina que define el tamaño de las esquinas
redondeadas.
8.4 Dynamic Binding and Abstract 205
Methods
206 8 Inheritance, Polymorphism and
Interfaces

La clase Square es una subclase de OneDimensionalShape , por lo que utiliza el


“ getDimension ” heredado. método para implementar sus propios métodos.
Utiliza el mismo método “ fillRect ” en la clase Graphics que Rectangle para
dibujarse a sí mismo.
8.4 Dynamic Binding and Abstract 207
Methods

Finalmente, el Triángulo Rectángulo clase es una forma bidimensional ,


Aunque sea es bastante posible eso el dos dimensiones eso son especificado podría
ser colocar a el mismo longitud. Calculando el área de a en ángulo recto triángulo es
simple desde él voluntad ser medio el área del delimitador rectángulo. Allá es No
método en el Gráficos clase a específicamente dibujar un triangulo Bastante, allá es
a “ rellenarPolígono ” método eso poder ser usado a dibujar cualquier polígono
cerrado . Este método toma como parámetros dos matrices de números enteros (las
coordenadas x y coordenadas y) y el número de agujas en el polígono. Para a
triángulo, de Por supuesto, habrá tres conjuntos de coordenadas y el número de
puntos será tres.
208 8 Inheritance, Polymorphism and
Interfaces

8.1.1 Usando Polimórfico Métodos

Una vez que hemos creado esta jerarquía polimórfica, ¿qué nos permite hacer? El
objetivo principal de este tipo de programación es permitirnos escribir estructuras
de control. en a nivel de abstracción eso da a nosotros flexibilidad acerca de
cómo nosotros manipular y interactuar con objetos. El siguiente ejemplo
demuestra el básico Principios. Comienza creando una matriz de formas. Cada una
de las formas que se crean es una instancia de una clase concreta, pero se accede a
ella a través de una referencia de la clase Shape. Dado que este ejemplo de código
solo prueba el método “ getArea ” de las clases, el método Point parámetro es no
usado y puede ser colocar a " nulo " . Después de la creación de el matriz, hay un
“ para ” bucle que itera a través de la matriz, invocando “ getArea ” método en
cada uno de los objetos. El punto clave aquí es que este código no necesita saber
nada sobre las clases reales de los objetos con los que se está comunicando. Aquí
solo se requieren los métodos declarados en la clase abstracta. En este caso,
8.4 Dynamic Binding and Abstract 209
Methods
estamos usando ambos el polimorfismo en nuestro propio jerarquía (el polimórfico
“ método getArea ” ) y el polimorfismo en las bibliotecas de Java (el método “
getClass ” método de Object y el método “ getSimpleName ” de la clase Class).
210 8 Inheritance, Polymorphism and
Interfaces

Este es el producción de el programa demostración respuestas a el mismo


método que se invoca en objetos de múltiples subclases:

Para ver el efecto polimórfico del “ draw ” métodos, necesitaremos crear un


método principal que pueda mostrar una ventana gráfica en la que se puedan
dibujar formas. Nosotros voluntad cubrir Interfaz de usuario programación en
mucho más detalle en más tarde capítulos pero aquí es una clase que muestra
algunas formas en una ventana gráfica. En este ejemplo, vemos una vez de nuevo
herencia y polimorfismo. Nosotros crear a subclase de JMarco , cual es el estándar
clase para creando a gráfico ventana en Java. Este ventana tiene es título, tamaño,
operación de cierre y visibilidad establecidos en el método “ principal ” . En la
subclase, anulamos a polimórfico método llamado " pintar " . Este método es
automáticamente Pasó una Objeto gráfico en tiempo de ejecución; nosotros hacer
no necesidad a crear a Gráficos objeto En cualquier lugar nuestro código, él es
creado para a nosotros. En el " pintar " método, nosotros llamar el superclase
versión del mismo método ( “ [Link] (g) ” ), que no es esencial para que el
programa funcione pero mejora el rediseño comportamiento si el ventana es
8.4 Dynamic Binding and Abstract 211
Methods
redimensionado, entonces crear La matriz de Formas, este tiempo donación a ellos
actual Punto parámetros a colocar su ubicaciones. Luego, un bucle “ for ” recorre
la matriz y llama a los distintos métodos “ draw ” .
212 8 Inheritance, Polymorphism and
Interfaces

El producción voluntad mirar como el ventana en Figura 8.11 : negro formas en a


F o n d o gris .
Ejercicio 8.4
• Agregar un Triángulo equilátero clase a un adecuado parte de el existente
j e r a r q u í a de formas .
• Implementar el “ getArea ” Método. Una búsqueda en la web le permitirá
encontrar rápidamente las fórmulas para calcular el área y la altura de un
triángulo equilátero.
• Implementa el método “ draw ” . Puedes usar el método “ fillPolygon ” para
dibujar el triángulo.
• Modifique las clases DrawFrame y ShapeAreas para que creen al menos una
instancia de su clase.
8.4 Dynamic Binding and Abstract 213
Methods

Higo. 8.11 Formas estirado usando El polimórfico " dibujar " método

8.2 Interfaces

Una interfaz es como una clase abstracta sin estado, en el sentido de que declara
métodos que tienen No implementación. Él es, entonces, simplemente a lista de
método firmas (aunque Existen algunas excepciones a esto, como veremos más
adelante). Sin embargo, existen algunas diferencias importantes entre clases e
interfaces. Java no admite herencia múltiple, por lo que una clase solo puede
extender otra clase. Sin embargo, con las interfaces, podemos elegir implementar
tantas como queramos en una sola clase. Implementar una interfaz significa
escribir código de implementación para cada uno de los métodos. en el interfaz.
Desde clases poder implementar múltiple interfaces, ellos Puede ser usado a
DIRECCIÓN “ transversal preocupaciones " Eso sería de lo contrario no encajar
pulcramente en una jerarquía de herencia. Diferentes clases pueden implementar
interfaces de manera polimórfica , así como anular los métodos de la superclase.
Puede tener múltiples referencias al mismo objeto, cada una exponiendo un
conjunto diferente de métodos, al mismo tiempo. múltiple interfaces en este forma
poder dar diferente Perspectivas en el mismo objeto, entonces un objeto de a
soltero clase puede llevar a cabo diferente roles en diferente regiones de una
aplicación.
8.5 211
Interfaces

Shape Transformable
location : Point
dimensions : int[]

getArea() : double switchDimensions()


draw(Graphics)

TwoDimensionalShape

getHeight() : int
getWidth() : int

Higo. 8.12 Forma bidimensional implementos el Interfaz “ transformable ”

En UML , la implementación de una interfaz se muestra con el mismo triángulo


. punta de flecha como herencia pero con a discontinuo bastante que a sólido
línea. En la Fig. 8.12 , se muestra la clase TwoDimensionalShape implementando
una interfaz llamada “ Transformable ” , con un método llamado “
switchDimensions ” . Observe cómo esta implementación de una interfaz
atraviesa la jerarquía de herencia.
Usamos la palabra clave “ interfaz ” en lugar de “ clase ” para declarar una
interfaz. El “ abstracto ” La palabra clave no se utiliza, ya que una interfaz es
automáticamente una abstracción. A nuevo interfaz poder ser creado en Java de el
" Archivo " menú o el ventana emergente menú Seleccionando " Nuevo " ! “
Interfaz ” . Este voluntad mostrar el diálogo caja mostrado en la Fig. 8.13 ,
que tiene menos opciones que la “ Nueva clase Java ” diálogo. Sin embargo, es
posible que una interfaz extienda otras interfaces, por lo que este diálogo incluye
una opción para agregar cualquier interfaz extendida.
Aquí, hemos creado una interfaz llamada “ Transformable ” (que no extiende
ninguna otra interfaz) y agregamos una única firma de método:
212 8 Inheritance, Polymorphism and
Interfaces

Higo. 8.13 Creando un interfaz En eclipse

Esta interfaz declara un “ switchDimensions ” método que algunas formas


(pero no todas) pueden implementar de alguna manera para cambiar sus
dimensiones. Debería ser razonablemente obvio que solo las formas
bidimensionales pueden cambiar sus dimensiones. La interfaz deja la
implementación completamente en manos de las clases implementadoras; todo lo
que necesitan hacer es anular la firma del método con una implementación
concreta del método.

8.2.1 Nombramiento Interfaces

Existen algunas convenciones comunes para nombrar interfaces. Debido a que las
interfaces no tienen estado y solo se relacionan con acciones de métodos, usar un
nombre de acción (que termine en “ able ” ) suele ser apropiado. Así es como
hemos nombrado la interfaz “ Transformable ” . Java sí mismo incluye varios
interfaces eso seguir este Nombramiento convención,
8.5 213
Interfaces
incluyendo “ Clonable ” (se puede copiar usando un método de “ clonación ”
personalizado ) y “ Serializable ” (poder ser serializado al otro lado de a
arroyo, semejante como a archivo o a red conexión). Estos tipos de " acción " Las
interfaces generalmente atraviesan jerarquías y solo especifican una pequeña
cantidad de métodos (a veces solo uno).
En otros casos se utilizan interfaces que tienen una relación uno a uno con el
concreto. clases en a específico implementación. Con este tipo de interfaz, él
Normalmente contiene a definición para todo (o mayoría) de el implementación
clase de público métodos. Hay son varios diseño Razones por qué él poder ser útil
a solo exponer un interfaz Al cliente código pero implementar él con a concreto
clase eso es no directamente accesible. Un ejemplo es el acceso a bases de datos,
donde un conjunto común de interfaces se implementa mediante diferentes
conjuntos de clases dependiendo de la plataforma de base de datos a la que se esté
conectando. como nosotros voluntad ver en Cap. 15 cuando nosotros mirar en Java
Base de datos Conectividad (JDBC). En casos como este, hay dos enfoques
generales.

1. Las interfaces se nombran utilizando nombres propios, pero las clases de


implementación terminan en “ Impl ” , por ejemplo, “ Curso ”. Interfaz y “
CourseImpl ” clase. Este es el tipo de enfoque que se adopta cuando las
interfaces están en las bibliotecas de Java y las clases concretas son
implementadas por terceros, como implementaciones externas de JDBC.
2. El nombre de la interfaz tiene como prefijo “ I ” y se utilizan nombres propios
para los nombres de clase, por ejemplo, la interfaz “ ICurso ” y la clase “
Curso ” . Este enfoque es el que probablemente adoptará al crear sus propias
interfaces, ya que el “ I ” El prefijo deja claro a los demás usuarios de su
código que se trata de una interfaz.

8.2.2 Implementando un Interfaz

Nosotros implementar un interfaz con el “ implementos ” palabra clave. El clase


debe Proporcionar implementaciones para todos los métodos de la interfaz. Este
ejemplo es una transformación simplista pero sirve para demostrar la idea de una
interfaz como un elemento transversal. inquietud.

En a similar forma a cómo a superclase referencia poder ser usado a referencia


un objeto de a subclase, un interfaz poder ser usado a referencia un objeto eso
214 8 Inheritance, Polymorphism and
Interfaces
implementos eso
8.5 215
Interfaces
Interfaz. Nuevamente, al igual que una superclase, la referencia solo se puede
utilizar para invocar métodos. eso son disponible en el referencia tipo. Este medio,
para ejemplo, eso si Creamos un RightAngledTriangle referenciado por una
referencia de interfaz Transformable, el único mensaje que podemos enviar a
través de esa referencia es “ switchDimensions ” .

Sin embargo, nosotros poder también hacer alguno traspuesta entre referencias
de diferente tipos, siempre que sean compatibles. Por ejemplo, podemos crear una
matriz de TwoDimensionalShapes .

Dado que TwoDimensionalShape implementa Transformable, podemos asignar


una referencia de matriz de Transformable para apuntar a la misma matriz.

Ahora podemos hacer referencia a la misma matriz utilizando diferentes tipos


de referencia : ¿recuerda cómo la asignación de referencias de objetos hace que
apunten a los mismos objetos? En este programa, nosotros crear un formación de
formas eso son también referenciado por La interfaz transformable. En un bucle “
for ” , primero dibujamos las formas en la posición actual. usando el formación de
Forma referencias, entonces transformar el mismo objetos utilizando la matriz de
referencias transformables, luego dibuje nuevamente utilizando las referencias de
forma. A hacer el producción a pequeño Más claro nosotros colocar el color de el
dibujo a dos tonos de gris utilizando un par de campos estáticos de la clase
[Link] .
216 8 Inheritance, Polymorphism and
Interfaces

Cifra 8.14 muestra el producción, con el cuatro formas transformado.


Ejercicio 8.5
• Crear un “ Giratorio ” Interfaz con un “ rotar ” método. Supongamos que este
método gira una figura 90° en el sentido de las agujas del reloj.
• Hacer cualquier clases implementar este interfaz eso tú pensar tú poder. Tú
puede Es necesario repensar la forma en que las formas almacenan actualmente
sus ubicaciones e información de dimensiones para lograr que giren de manera
adecuada.
• Habiendo implementado una “ rotación ” método, agregue más métodos a la
8.5 217
Interfaces
interfaz para proporcionar varios tipos de rotación.
218 8 Inheritance, Polymorphism and
Interfaces

Higo. 8.14 Formas transformadas por El “ Transformable ” interfaz

Ejercicio 8.6
El método “ draw ” se relaciona con representaciones gráficas de formas, pero la
jerarquía de formas se puede utilizar en contextos en los que no se requieren vistas
gráficas. Esto significa que “ draw ” se puede especificar mejor mediante una
interfaz, separada de la jerarquía de formas.

• Extracto el método de “ dibujar ” en un interfaz y eliminar él de el clases


abstractas .
• Hacer el concreto clases implementar el " dibujar " método.
• Modificar el Trabajo de dibujo clase entonces eso él Sorteos el formas usando su
interfaz.

Ejercicio 8.7
• Modificar el juego Serpientes y Escaleras para que tanto Serpiente como
Escalera sean subclases de una superclase llamada Mover.
8.5 219
Interfaces
• Sus métodos comunes deben incluirse en Mover. Deben contener solo sus
propios constructores y un ' showMessage ' polimórfico. método que
muestra si el objeto es una serpiente o una escalera.
• Modifique la clase BoardSquare para que tenga una referencia a un objeto
Mover en lugar de referencias a una serpiente y una escalera.
• Utilice esta referencia para crear el tipo apropiado de objeto de subclase
(Serpiente o Escalera) en los cuadrados correctos.
• se haya modificado la clase BoardSquare , puede cambiar el mecanismo de
paso de mensajes descrito en la Fig. 7.14. a uno que utiliza los métodos
polimórficos de Agente de mudanzas a mover el Pieza de jugador a el correcto
cuadrado. Asegurar eso ¡Todo el juego todavía funciona!

8.2.3 Más Aspectos de Interfaces

En este capítulo, hemos definido las interfaces como aquellas que contienen solo
uno o más métodos abstractos. firmas. El implementación de estos métodos es
hecho en cualquier clases que implementan la interfaz. Un problema potencial con
esto es que si se agrega una nueva firma de método a una interfaz existente, esto
romperá todas las clases que ya implementan esa interfaz, ya que ahora se les
exigirá que implementen la nueva método. A superar este problema, Java 8
introducido el capacidad a agregar métodos predeterminados a un interfaz. Este
era no justo para el beneficio de desarrolladores escribiendo Código Java, él era
también necesario para el desarrolladores de Java sí mismo a ser capaz a
Rediseñar partes del JDK para incorporar expresiones lambda en interfaces
existentes y hacerlas compatibles con el código existente. No es necesario que las
clases que implementan la interfaz implementen un método predeterminado,
aunque pueden anular opcionalmente la implementación predeterminada.
Como ejemplo de una interfaz con un método predeterminado, presentaremos
otro método a nuestra interfaz Transformable existente llamado “ resizeBy ” .
Una clase que implementa este método podría permitir un objeto a cambiar el
tamaño sí mismo basado en a escalada factor. La interfaz modificada podría verse
así:

El problema aquí, por supuesto, es que cualquier clase que actualmente


implemente el Transformable interfaz voluntad ser roto porque ellos hacer no
actualmente implementar el “ cambiar de tamaño ” método. El solución a este
negativo impacto en existente código es a hacer que “ resizeBy ” sea un método
predeterminado, con una implementación predeterminada:
220 8 Inheritance, Polymorphism and
Interfaces

En este ejemplo, no hay ningún comportamiento predeterminado significativo


que se pueda proporcionar, ya que en este contexto la interfaz no puede conocer
ningún estado de objeto que pueda estar relacionado. a tamaño. Cualquier objeto
eso ya implementos el “ Transformable ” interfaz y llamar a este método solo
generará un mensaje de error en tiempo de ejecución. Sin embargo, en otras
situaciones, un método predeterminado podría incluir algún código significativo
que no requiera ningún estado de objeto en su implementación.
Con la implementación predeterminada, cualquier clase que implemente la
interfaz puede electo a anular el por defecto implementación de “
redimensionarPor ” . Para ejemplo, aquí es una implementación de “ resizeBy ”
en “ TwoDimensionalShape ” que aplica el factor de escala a ambas dimensiones.

Por supuesto, puede que estés pensando que este comportamiento de cambio de
tamaño debería aplicarse a todas las formas, no solo a las bidimensionales. Esto es
consecuencia de construir una arquitectura a partir de ejemplos de sintaxis en
lugar de hacerlo a partir de buenos principios de diseño. Siéntete libre de mejorar
el diseño como creas conveniente.
Él es también posible para interfaces a tener privado métodos. Para ejemplo,
8.5 221
Interfaces
nosotros Podría elegir a usar alguno interno encapsulamiento en el por defecto
método de un interfaz. Ya hemos cubierto la sintaxis de los métodos privados , por
lo que no agregaremos más ejemplos aquí.
Otra característica de las interfaces que se introdujo en Java 8 fue la opción de
incluir métodos estáticos. Como hemos visto en ejemplos anteriores, un método
estático es aquel que puede ser ejecutado directamente por la clase, en lugar de ser
invocado por un objeto. Por lo tanto, un método estático en una interfaz puede ser
llamado directamente utilizando la interfaz. Estático métodos no puedo acceso
objeto estado directamente y debe tener a Implementación útil o allá es No
punto en teniendo a ellos. Ellos también necesidad a tener a
222 8 Inheritance, Polymorphism and
Interfaces
significativo semántico relación con el interfaz. El siguiente ejemplo añade un
método estático para la interfaz transformable llamado “ isTransformable ” . Para
reducir la cantidad de sintaxis nueva en este ejemplo, esta no es la mejor
implementación posible de este método, pero será suficiente para demostrar el
principio de un método de interfaz estático.
La implementación de “ isTransformable ” El método se basa en algún código
de reflexión , a saber, el “ obtenerInterfaces ” método de el Clase clase . Este
devoluciones un formación De todos el interfaces implementado por el clase, pero
solo aquellos directamente implementado por ella, no las implementadas por
superclases . Por lo tanto, para que este ejemplo funcione, necesitaremos agregar “
implements Transformable ” a la firma de la clase Rectangle. Tenga en cuenta que
debido a que su superclase ( TwoDimensionalShape ) ya implementa esta interfaz,
Rectangle no necesita proporcionar ningún código de implementación.

El siguiente ejemplo es una implementación de “ isTransformable ” Método de


los “ Transformables ” Interfaz. Por supuesto, es un método estático. Toma una
forma como argumento, ya que el método no puede saber nada sobre el estado del
objeto a menos que se le pase un objeto. “ getClass (). getInterfaces () ” se llama
para obtener una matriz de interfaces implementadas por la clase, que (por
simplicidad ) convertimos en una cadena usando el método estático “ toString ”
de la clase Arrays que puede convertir el contenido de una matriz en una sola
cadena (obtendrá una advertencia del compilador en esta línea pero nosotros no
puedo arreglar eso hasta nosotros tener introducido genéricos en a más tarde
capítulo). Entonces Utilizamos el método “ contains ” de la clase String para ver
si el nombre de la interfaz Transformable está en la matriz. Si es así, devolvemos
“ true ” , de lo contrario, devolvemos “ false ” .
8.5 223
Interfaces

A continuación se muestra una clase de prueba breve que crea un cuadrado y


un rectángulo. Solo el rectángulo implementa directamente la interfaz
Transformable.
224 8 Inheritance, Polymorphism and
Interfaces

El producción de correr este código es como Sigue:

8.3 Lambda Expresiones

Otro cambio significativo en las interfaces en Java 8 fue la capacidad de usar


expresiones lambda. a implementar cualquier interfaz eso tiene a soltero abstracto
método. A La expresión lambda es simplemente una función anónima que no tiene
nombre. Su valor principal es el de una forma abreviada de escribir código que
permite escribir una función. Implementación en el mismo lugar tú son yendo a
usar él. Este es particularmente útil si tu eres solo ir a usa esa función En uno
lugar, y el implementación es corto. Evita tener que declarar y escribir un método
separado en una clase en algún otro lugar del código base.
A llevar a paso atrás, y poner Java lambda expresiones en contexto, nosotros
debería En primer lugar, cabe señalar que Java no admite funciones
independientes. En un lenguaje orientado a objetos , las funciones siempre
pertenecen a una clase o a un objeto : son métodos de clase o de objeto. Los
métodos de objeto se basan en un conjunto de estados que se relacionan con un
8.5 225
Interfaces
objeto específico. Sin embargo, en los últimos años se ha producido un
movimiento hacia lenguajes que admiten funciones independientes. funcional
programación, como Haskell, Escala, Erlang, Ceceo y Clojure. El requisito
principal de un lenguaje de programación funcional es que admita funciones
independientes, pero Java siempre ha estado orientado a objetos y funciones
independientes. tener no estado apoyado. En a funcional idioma (en el menos en el
nivel más simple) funciones hacer no mantener cualquier estado, y si estado
datos es aprobado alrededor
8.6 Lambda 221
Expressions
entre funciones entonces él es inmutable (es decir no puedo ser cambió).
Funciones poder También ser aprobado alrededor como referencias y usado como
el parámetro argumentos o devolver tipos de otras funciones (estas se conocen
como funciones de orden superior).
Dado que ambos tipos de programación tienen sus ventajas (programación
funcional ) es particularmente útil para concurrente sistemas) él hecho sentido
para Java a incluir al menos algunas características de la programación funcional.
Supongamos que Java admitiera funciones independientes. Como no
mantendrían ningún estado interno, esperaríamos que recibieran cualquier estado
que fuera necesario procesar como argumento de parámetro y que devolvieran
cualquier resultado de la función. Para dar un ejemplo muy simple, podríamos
tener una función que comparara dos números y devolviera el mayor de ellos. La
función podría verse así (no es una función anónima, pero ayudará a desarrollar la
sintaxis lambda de Java):

A usar el función, nosotros quería justo necesidad a llamar él directamente:

Sin embargo, desde Java hace no apoyo semejante funciones, a diferente


mecanismo Se necesitaba una arquitectura orientada a objetos que se ajustara a
ella. Aquí es donde entran en juego las expresiones lambda.
El lambda expresiones introducido con Java 8 apoyo (arriba a a punto)
funciones que hacer no pertenecer a clases. Uno de el Razones para Presentando
lambda expresiones es a reducir código complejidad. A menudo, Java requiere a
nosotros a crear objetos a anfitrión Un solo función, cuando él quería ser a lote
Más simple justo a escribir el función en es propio. Es importante señalar que Java
no se ha convertido de repente en un lenguaje funcional.
Más bien, apoya algunos aspectos de programación funcional en el contexto de la
implementación de ciertos tipos de interfaz .

8.3.1 Lambda Expresión Sintaxis

Allá son a pocos variaciones en código estilo eso poder ser usado cuando escribiendo
Expresiones lambda, pero en su forma más simple, el formato de una expresión lambda es
222 8 Inheritance, Polymorphism and
Interfaces
Nota el flecha operador (a menos personaje seguido por a mayor que que
personaje) que indica a lambda expresión (nosotros primero sierra este operador
en Cap. 4 en el
8.6 Lambda 223
Expressions
contexto de la expresión switch). Las expresiones lambda en Java solo se pueden
utilizar en el contexto de interfaces eso tener a resumen único método a ser
implementado (sin incluir ningún método privado, predeterminado o estático que
la interfaz también pueda tener). Dado que allá es No ambigüedad acerca de cual
método es ser implementado, el código porque la expresión puede ser bastante
simple.
Debido a que una expresión lambda de Java requiere una interfaz con un único
método abstracto, nuestro ejemplo método quería tener a ser parte de un interfaz.
Para ejemplo:

Nota el " I " prefijo tipo de interfaz nombrando, desde el " capaz " sufijo
nosotros tener El uso que se ha hecho realmente no tiene sentido con funciones
que no se implementan mediante objetos.
En el siguiente ejemplo de código, el método se implementa mediante la
expresión lambda, mientras que la referencia de interfaz “ compareImpl ” nos da
una referencia a través de la cual podemos llamar a la función posteriormente.

Nosotros poder entonces invocar el lambda expresión usando el Interfaz referencia


“ compararImpl ” .

Lo más importante a tener en cuenta es que no necesitábamos crear una clase


para implementar la interfaz; solo necesitábamos proporcionar la implementación
de la función como una expresión lambda.
Una cosa más que podemos notar sobre nuestra expresión lambda es que (como
“ var ” ) puede usar tipo inferencia, dónde el compilador poder inferir el tipo de a
datos artículo de El contexto. El siguiente versión de el lambda expresión es
también perfectamente bien — note cómo allá es No necesidad a proporcionar el
tipo (doble) de el dos argumentos — esto poder se puede inferir de la firma en la
interfaz.
224 8 Inheritance, Polymorphism and
Interfaces
8.6 Lambda 225
Expressions
Allá son muchos otro aspectos a lambda expresiones, alguno de cual
nosotros nos encontraremos en los próximos capítulos.
Ejercicio 8.8
• Crea una interfaz llamada IAverage con un método llamado “ getMean ” que
toma una matriz de dobles como argumento y devuelve un doble.
• Agregue un método privado a la interfaz que toma una matriz de dobles como
argumento y calcula y devoluciones el significar promedio de el valores en el
formación.
• Agregue un método predeterminado a la interfaz que llama al método privado
para calcular y devolver el promedio medio de una matriz de dobles.
• Cree una clase que implemente la interfaz pero no proporcione una
implementación del método “ getMean ” .
• Crea una clase con un “ main ” método que crea una instancia de su clase que
implementa el interfaz y invoca el “ obtenerMean ” método (el por defecto se
llamará al método en la interfaz).

Ejercicio 8.9
En el ejercicio anterior se utilizaron métodos predeterminados y privados para
implementar el método “ getAverage ” de la interfaz IAverage . En este
ejercicio, utilizaremos una expresión lambda para implementar un método de la
interfaz. Esto requiere que la interfaz tenga un único método abstracto.

• Agregar un abstracto método llamado “ obtenerPromedio ” a el Promedio


interfaz eso toma una matriz de dobles como argumento y devuelve un doble.
• Cree una clase con un método “ principal ” y agregue código que implemente
“ getAverage ” método de la interfaz que utiliza una expresión lambda que
calcula el promedio medio de una matriz de dobles.
• Agregue otra expresión lambda que implemente el método “ getAverage ” para
que devuelva el promedio mediano de una matriz de dobles (suponga que la
matriz está ordenada).

8.4 Resumen

En este capítulo, hemos visto cómo se puede utilizar la herencia para escribir
clases estrechamente relacionadas que tienen algunos campos y métodos en
común. En los ejemplos de código, un conjunto de clases eran organizado en un
herencia jerarquía de súper y subclases que iba más allá del comportamiento
predeterminado de las clases Java para heredar directamente de la clase “ Object ”
. Este uso de la herencia se construyó para demostrar cómo los métodos
polimórficos poder ser escrito eso permitir objetos de diferente clases a responder
de forma diferente a las mismas llamadas de método. Se mostraron algunos
ejemplos de clases que proporcionan polimorfismo. Implementaciones de
métodos heredado de el " Objeto " clase, semejante como
226 8 Inheritance, Polymorphism and
Interfaces
“ toString ” . El papel de las clases y métodos abstractos en las
jerarquías de herencia se demostró mediante la vinculación dinámica de una
referencia de superclase a un objeto de subclase . La palabra clave se introdujo
en el contexto de llamar a los métodos y constructores de una superclase, y la
anotación “ @Override ” se utilizó para garantizar que los métodos anularan
correctamente los heredados de una superclase. El capítulo también explicado
cómo Java interfaces poder ser usado a proporcionar común servicios a través de
una gama de clases de implementación y concluyó explorando algunas de las
mejoras en las interfaces introducidas con Java 8, incluidos los métodos
predeterminados, los métodos privados y las expresiones lambda.
Excepción Manejo
9

Excepciones son un importante aspecto de Java programación porque ellos


permitir a nosotros para manejar de manera eficiente y orientada a objetos el flujo
inusual del programa , ya sea causado por problemas técnicos o procesos de
negocios. Antes de los lenguajes con manejo de excepciones incorporado, tales
problemas debían ser manejados manualmente error códigos alrededor a
programa, sin cualquier encapsulamiento o estándar Maneras de manejarlos.
Excepciones cubrir a rango de asuntos de importante programación errores
como dividir un entero por cero, o intentar invocar métodos en una referencia
nula, hasta pequeñas excepciones del proceso de negocio, como un usuario que
ingresa un código de área no válido en su dirección.

9.1 Java Excepciones

Cuando surge una condición inusual en el código Java, puede generar una
excepción. Esto significa que crea un objeto que representa esa excepción,
encapsula cierta información sobre ella y le da al programa la oportunidad de
hacer algo al respecto. Si no se hace nada, el programa finalizará. Como no
queremos que un programa finalice de forma arbitraria, necesitamos escribir
código que sea capaz de detectar y manejar cualquier excepción. eso puede surgir.
En alguno casos, el compilador requiere a nosotros a escribir código que pueden
manejar excepciones. En otros casos, necesitamos anticiparnos a la posibilidad
nosotros mismos . Además, hay lugares donde podemos querer crear excepciones
explícitamente, en situaciones donde se ha violado una regla de negocios. Java
proporciona sintaxis para manejar todas estas posibilidades.

© Saltador Naturaleza Suiza Estado 2020 225


D. Parsons, Foundational Java , Textos en
Ciencias de la Computación,
[Link]
226 9 Exception
Handling
9.1.1 El Excepción Manejo Jerarquía

El clases en Java eso relatar a excepción manejo aparecer en a jerarquía (Higo. 9.1
). En la parte superior de la jerarquía se encuentra el “ Throwable ” clase, que
representa todo tipo de errores y excepciones que pueden ocurrir en un programa
Java. Un objeto Throwable puede ser creado por la máquina virtual Java en tiempo
de ejecución o creado explícitamente usando la palabra clave “ throw ” (ver Tabla
9.1 ). Hay dos tipos de Throwable: errores y excepciones. Los programadores no
necesitan preocuparse por instancias de la clase Error, desde estos representar
tiempo de ejecución errores eso aplicaciones no puedo ser esperado a hacer
cualquier cosa acerca de. Uno ejemplo de un Error subclase es Error de máquina
virtual . Este un poco El error es no algo que el aplicación promedio es
Probablemente ser capaz a recuperarse de. Sin embargo, los programadores de
aplicaciones deberían poder hacer algo con las instancias de Excepción y es
subclases. Como el Javadoc para Excepción dice, “ La clase Excepción y es
subclases son a forma de Arrojable eso indica condiciones que una aplicación
razonable podría querer capturar ” .

Throwable

desenfrenado errores

Error Exception

comprobado excepciones
desenfrenado excepciones

RuntimeException All Other Subclasses

Subclasses

Higo. 9.1 El Java excepción y error jerarquía


9.1 Java Excepciones 227

Mesa 9.1 Java excepción manejo Palabras clave

Palabra Uso
clave
lanza Indica eso a método puede tirar un excepción
intentar Encierra a bloquear de código eso puede tirar un excepción
atrapar Sigue “ intentar ” —encierra a bloquear de código eso es invocado si
a especificado excepción es arrojado
Finalment Sigue " try " o “ catch ”: encierra un bloque de código que se ejecuta
e independientemente de si se lanzan excepciones
tirar Permite el programador a explícitamente tirar un excepción

9.1.2 Comprobado y Desenfrenado Excepciones

Hay otra capa de la jerarquía debajo de la clase Exception que afecta la forma en
que manejamos las excepciones. Una de las subclases de Exception es
RuntimeException . Esta clase, y todas sus subclases, representan excepciones que
pueden lanzarse durante el funcionamiento normal de la máquina virtual Java (a
diferencia de la aplicación). errores). Estos son conocido como “ sin marcar ”
excepciones porque nosotros son El compilador no requiere que manejemos
ninguna de estas excepciones, aunque podríamos elegir a hacer entonces a
prevenir a ellos causando nuestro programas a terminar. En contraste, Las otras
excepciones que son subclases directas de Excepción son “ checked ”
excepciones, que medio eso el compilador voluntad asegurar eso nosotros hacer
algo en nuestro Código de aplicación para manejarlos.

9.1.3 Excepción Manejo Palabras clave

Las palabras clave de Java relacionadas con el manejo de excepciones se muestran


en la Tabla 9.1 . Nótese la distinción entre “ throws ” , que puede aparecer en la
firma de un método, y “ throw ” , que se utiliza para lanzar explícitamente una
excepción. una excepción en el cuerpo de un método.

9.2 Manejo Comprobado Excepciones

Java comprobará, en tiempo de compilación, si está intentando hacer algo que


podría generar una excepción comprobada y, en caso afirmativo, si su programa
contiene el código necesario para manejar dicha excepción. Nuestro primer
ejemplo utiliza la clase System. cual (en suma a teniendo un " afuera " objeto
campo) tiene un " en " objeto campo (una instancia de una subclase concreta de la
clase abstracta InputStream ), con cero argumentos " leer " método que lee el
siguiente byte de datos del flujo de entrada. En realidad, devoluciones un entero,
pero solo uno byte de el entero es poblado con datos. Este es
228 9 Exception
Handling
Adecuado para leer un carácter Unicode del teclado en el rango 0 – 255. La
segunda línea del siguiente “ main ” El método convierte el int en un char para
que el carácter es desplegado bastante que el Unicode valor. Como él se encuentra,
este código voluntad No compilar . El compilador señalará el error “ Tipo de
excepción no controlada IOException ” ( IOException está en el paquete
[Link]).

paquete
[Link] .chapter9;
clase pública
ReadFromKeyboard
{
público estático vacío principal( Cadena[] argumentos )
{
entero miChar = [Link] (); // voluntad no compilar
[Link] (( char ) miChar );
}
}

El problema es con el Flujo de entrada " leer " método, cual lanza [Link].
Excepción IO , a comprobado excepción. El excepciones eso poder ser arrojado
por a Los métodos son fijado en el método declaración, y el Javadoc para a clase
voluntad decir tú si cualquiera de es métodos tirar excepciones. Si tú controlar el
Javadoc para el Flujo de entrada clase, verás que la firma del método “ read ” es.

público abstracto entero leer( ) lanza Excepción de E/S

Si solo queremos la ruta más corta para compilar el código, la respuesta mínima
es reconocer que puede ocurrir una excepción al usar “ [Link]. read ”
simplemente volviendo a generar la excepción. Esto significa agregar otra cláusula
“ throws ” a la firma del método que realiza la llamada, en este caso, “ main ” .

público estático vacío


principal( Cadena[] args )
lanza [Link]

Esto permite que la clase se compile sin tener que lidiar con ninguna excepción
que pueda surgir. arrojado en tiempo de ejecución. Si un excepción hace ocurrir, el
programa voluntad terminar. En En la siguiente versión de la clase, el código se
compilará porque hemos agregado " throws " Excepción de E/ S ” a el firma de el
" principal " método (el Excepción de E/S (La clase también ha sido importada).

paquete
[Link] .chapter9;
importar [Link]
; clase pública
ReadFromKeyboard
{
público estático vacío
principal( Cadena[] args ) lanza
[Link]
{
int miChar = [Link] ();
[Link] ((char) miChar );
9.2 Handling Checked 229
Exceptions
}
}
230 9 Exception
Handling

Higo. 9.2 Usando el consola para ambos aporte y producción en eclipse

En Eclipse, cuando ejecutamos un programa que utiliza “ [Link] ” , la


consola de salida también se utiliza para la entrada. Para finalizar
la entrada, presione la tecla Enter. El método “ read ” capturará
únicamente el primer carácter ingresado . Figura 9.2 muestra que se ha escrito el
carácter “ a ” y luego se ha devuelto a la misma consola.

9.2.1 Atractivo Excepciones: “probar” y "atrapar"

Simplemente volver a lanzar una excepción verificada desde el método " principal
" no es una solución particularmente bien forma de relación comercial con él. El
razón para teniendo comprobado excepciones es Que ellos puede ocurrir, entonces
básicamente postergación a ellos voluntad no dirigir a muy robusto aplicaciones.
Por lo tanto, en lugar de simplemente volver a generar una excepción, deberíamos
hacer algo para capturarla nosotros mismos. Esto tiene el beneficio de permitir que
un programa continúe ejecutándose incluso si se produjo una excepción. La
sintaxis para hacer esto se basa en las palabras claves “ try ” y “ catch ” :

intentar
{
// hacer este
}
atrapar( una excepción mi)
{
// si él todo fue terriblemente equivocado, hacer este
}

“ una excepción ” debe cualquiera ser uno de el predefinido excepción clases eso existir
en Java o un objeto de una subclase de excepción que hayamos escrito nosotros
mismos (veremos cómo escribir y usar subclases de excepción personalizadas más
adelante en este capítulo). También debe ser una excepción que podría ser lanzada
por el código en el bloque “ try ” .
El siguiente ejemplo utiliza una versión ligeramente diferente del método “
read ” que permite más que uno personaje a ser entró en un formación de bytes.
De nuevo, él lanza [Link] .

público abstracto entero leer( byte[ ] b) lanza Excepción de


E/S
9.2 Handling Checked 231
Exceptions

Desde el formación de bytes es no a Cadena, si tú simplemente leer el


personajes en El byte buffer y mostrar él, él voluntad no aparecer en el consola
como a cadena de personajes. Por lo tanto, un intermedio El paso es requerido,
dónde nosotros crear a Cadena desde matriz de bytes. También es necesario
eliminar los espacios finales de la cadena, lo que se puede hacer con el " recortar "
método. Este línea de código hace el conversión por usando uno de los muchos
constructores disponibles para la clase String y luego recorta la cadena:

cadena de entrada = nuevo Cadena(buffer ).trim ();

Nota
Si desea asegurarse de eliminar cualquier tipo de espacio inicial o final que
aparezca en cualquier parte de la tabla Unicode , puede utilizar el método " strip
". en lugar de “ recortar ” .
En el siguiente ejemplo, el " leer " código es poner en a " intentar " bloquear, y
cualquier
La excepción IOException que se puede lanzar se captura en el bloque “ catch ” .
Debemos hacer algo dentro de una " atrapar " bloque. Si detectamos una
excepción pero no hacemos nada, Entonces, se pierde toda la información que
estaba disponible en la excepción original para decirnos qué sucedió . Lo mínimo
que debe hacer en un bloque " catch " es mostrar, o de otra manera registrar,
información sobre la excepción. Una forma sencilla de hacer esto es llamar al
método " printStackTrace " en el objeto de excepción que se genera cuando se
produce la excepción . es arrojado. Este es proporcionó como a parámetro a el "
atrapar " bloquear. Ahora que la excepción se maneja en el bloque “ try-catch ” ,
el método “ main ” ya no necesita tener un “ throws ” cláusula. Una cosa a tener
en cuenta sobre “ try-catch ” Los bloques son eso porque de alcance nosotros a
menudo necesidad a declarar variables afuera de el " intentar " bloque para
hacerlos visibles después del “ catch ” , como en este ejemplo.
paquete
[Link] .chapter9;
público clase Leer búfer desde
el teclado
{
público estático vacío principal( Cadena[] argumentos )
{
byte[ ] buffer = nuevo byte[10];
Cadena cadena de
entrada = nulo;
intentar
{
[Link] (búfer );
cadena de entrada = nuevo Cadena(buffer ).trim ();
}
captura( [Link] mi)
{
[Link] ();
}
[Link] ( cadena de entrada );
}
}
232 9 Exception
Handling

Higo. 9.3 Usando el eclipse consola para entrando instrumentos de cuerda de personajes

Ahora bien, si un IOException es arrojado por el " leer " método, en lugar de el
programa terminando, el código en el “ catch ” Se ejecutará el bloque. Figura 9.3
muestra la consola de entrada/salida cuando se ejecuta este programa.

9.3 Manejo Desenfrenado Excepciones

Cuando se utiliza código que genera excepciones controladas, el compilador no le


da otra opción que hacer algo al respecto. Además, puede, si lo desea, gestionar
también las excepciones no controladas. Un ejemplo de una excepción no
controlada es ArrayIndexOutOfBoundsException . Por ejemplo, este fragmento de
código se compilará, pero generará una ArrayIndexOutOfBoundsException en
tiempo de ejecución tan pronto como intente acceder al índice 3 de la matriz:
paquete
[Link] .chapter9;
público clase Ejemplo de
índice de matriz
{
público estático vacío principal( Cadena[] argumentos )
{
entero[ ] matriz int = nuevo int[3];
para( int i = 0; i < 5; yo ++)
{
matriz int [ i ] = i ;
[Link] ( intArray [ i ] );
}
}
}

La salida mostrará algo parecido al siguiente mensaje (el orden de la salida


estándar y de error puede mezclarse en Eclipse ya que utilizan diferentes flujos de
salida):
Excepción en hilo
"principal" 0 1
2
[Link]
n : 3 en
[Link]
( ArrayIndexExample
.java:10)
9.2 Handling Checked 233
Exceptions
En contraste, este versión de el principal método capturas el MatrizIndexFueraDe
BoundsException y permite que el programa finalice normalmente.
paquete
[Link].chapter9 ;
público clase Ejemplo de
índice de matriz
{
público estático vacío principal( Cadena[] argumentos )
{
entero[ ] matriz int = nuevo int[3];
para (en el interior i = 0; i < 5; yo ++)
{
intentar
{
intArray [ i ] = i ; [Link]
( intArray [ i ] );
}
atrapar ( Excepción ArrayIndexOutOfBounds mi)
{
[Link] ();
}
}
}

Esta vez, la salida muestra que se ha lanzado la excepción, pero el bucle


continúa después de que se haya impreso el seguimiento de la pila. Se producen
dos excepciones ArrayIndexOutOfBounds , pero el programa continúa hasta el
final del bucle.
0
1
2
[Link]
on : 3 en
[Link]
( ArrayIndexExample
.java:11)
[Link] .ArrayIndexOutOfBoundsExcept
ion : 4 en
[Link]
( ArrayIndexExample
.java:11)

9.3.1 Saliendo

En la mayoría de los ejemplos de este capítulo, una “ captura ” El bloque será una
oportunidad para ignorar una excepción y continuar o hacer algo para solucionar
el problema en tiempo de ejecución. En algunos casos, sin embargo, se produce
una excepción en la que no tiene sentido permitir que se ejecute. el programa a
continuar como él no puedo razonablemente recuperar. En casos como Esto lo
234 9 Exception
Handling
podemos hacer de forma explícita, saliendo del programa, utilizando el comando “
[Link] ”. Método. Este método toma un parámetro entero, donde un valor
distinto de cero indica una salida anormal. Aquí, por ejemplo, agregamos un “
[Link] ” a un bloque “ catch ” y usamos el valor “ 1 ” (una terminación
anormal).
9.3 Manejo Desenfrenado Excepciones 233

captura( Excepción mi)


{
[Link] ();
[Link] (1);
}

9.4 Atractivo Múltiple Excepciones

Cuando escribiendo código dónde muchos diferente excepciones puede ser


arrojado, él poder conseguir bastante feo y complejo a tener a entero serie de
separado “ Intenta atrapar ” bloques uno después el otro. A mejor acercarse es a
tener a soltero bloquear de código eso puede potencialmente Lanzar más de un
tipo de excepción. Para manejar esta situación, un solo intento Un bloque
puede tener más de un bloque “ catch ” a continuación. En el siguiente ejemplo,
usamos “ [Link] ”. a intentar a leer a número de el teclado. Desde el
pulsaciones de teclas originales son leer como un formación de bytes, nosotros
necesidad alguno forma de mudado estos En un número. Nosotros tener ya visto
cómo a convertir a byte formación en a recortado Cadena. Ahora necesitamos un
medio para convertir una cadena en un número.
Como sabemos, Java tiene objetos y tipos primitivos (int, double, etc.). Para
proporcionar un puente entre ellos, Java proporciona un conjunto de clases
contenedoras para todos los objetos integrados. tipos Permitiendo a nosotros a
convertir primitivos a objetos y vicio viceversa. Allá son clases para todo el tipos
de números incluido Flotar, Entero, Doble y Largo. Una ventaja de estos clases es
eso ellos proporcionar estático conversión métodos a convertir cadena
representaciones de números en primitivo valores. Para ejemplo, el Método “
parseInt ” de La clase Integer toma una cadena como parámetro y devuelve un
valor int datos tipo. Por este método, nosotros poder fácilmente convertir un
Cadena a un entero, Por ejemplo,

entero unInt = [Link] ("12345" );

Si el Cadena aprobado como a parámetro no puedo ser convertido a un entero,


el método generará una excepción [Link] .NumberFormatException , aunque no
es necesario colocar el método en un bloque try para compilarlo porque se trata de
una excepción no controlada. Sin embargo, él poder ser a útil excepción a
controlar para, entonces nosotros voluntad hacer entonces en este Ejemplo. Este es
el completo clase con a soltero " intentar " bloquear seguido por dos " atrapar "
bloques:
234 9 Exception
Handling

paquete [Link]ítulo9 ;
público clase Leer entero desde el teclado
{
público estático vacío principal( Cadena[] argumentos )
{
byte[ ] buffer = nuevo
byte[10]; int entradaInt
= 0;
intentar
{
[Link] (búfer );
Cadena cadena de entrada = nuevo Cadena(buffer
).trim (); inputInt = [Link]
( entradaString );
}
captura( [Link] mi)
{
[Link] ();
}
captura( Excepción de formato de número mi)
{
[Link] ();
}
[Link] ( entradaInt );
}
}

Dado cualquier aporte eso poder ser convertido en un entero valor, el programa
voluntad ejecutar sin lanzar una excepción. Por otro lado, ingresar cualquier
carácter no numérico provocará que se lance la NumberFormatException :
a
[Link] : Para aporte
cadena: "a" en
[Link] .[Link] (fuente
desconocida) en [Link] (fuente
desconocida)
en [Link] .[Link]
(Desconocido Fuente) 0
en [Link] (
[Link])

9.4.1 Realizar pedidos Múltiple "atrapar" Bloques

Como se muestra en el ejemplo anterior, puedes capturar cualquier cantidad de


excepciones al final de un solo " try ". bloque, cada uno en su propia “ captura ”
bloque. En el último ejemplo, las dos excepciones estaban en diferentes partes de
la jerarquía, por lo que no interferirían entre sí. otro. Sin embargo, si tú tener
superclase y subclase excepciones siguiente el mismo " intento " Bloquea,
entonces tú Hay que poner el “ capturador ” bloques en orden desde abajo hacia
arriba de la jerarquía, por ejemplo,
9.4 Atractivo Múltiple Excepciones
236 9 Exception 235
Handling

intentar
{

}
captura( IOException mi)
{

}
captura( Excepción mi)
{

}

La razón de esto es que si pones una excepción, que está más arriba en la
jerarquía, primero, entonces ese “ catch ” El bloque será el primero en coincidir.
En el ejemplo anterior, si el orden de los bloques " catch " Los bloques se
invirtieron, ya que IOException es una subclase de Exception, si se lanza uno, el
bloque Exception se coincidirá primero y nunca se alcanzará el bloque de captura
IOException .
Ejercicio 9.1
En este sección, nosotros tener miró en alguno aspectos de manejo básico teclado
aporte en Java. Dado que esto no es particularmente simple, es Resulta útil
encapsular el código que maneja la entrada del teclado dentro de una clase. Crear
una clase de teclado reutilizable significa eso nosotros hacer no tener a escribir el
mismo código repetidamente cada tiempo nosotros desear para obtener algunos
datos del teclado.

• Cree una clase de teclado reutilizable que incluya métodos para leer un solo
carácter, una cadena o un entero del teclado.
• Incluir el requerido excepción manejo.
• Agregar a método a aporte a punto flotante número, usando el “ parseDouble
” método de la clase Double para implementar el método.
• Prueba su Teclado clase en a método “ principal ” .

9.5 Lanzamiento un Excepción con "tirar"

En el ejemplos, nosotros tener visto entonces lejos, nosotros tener estado usando
Java excepciones eso tal vez arrojado por el Java virtual máquina. A veces, sin
embargo, nosotros necesidad a tomar responsabilidad para lanzamiento
excepciones nosotros mismos. Este es qué el " tirar " La palabra clave es para, él
permite a nosotros a elegir situaciones en cual nosotros desear a crear y Lanzar
excepción objetos, generalmente en respuesta a alguno negocio regla eso tiene
estado violado. Volver en Cap. 6 , nosotros miró en el role de “ establecedor ”
métodos en guardando un objeto campos de ser colocar a inadecuado valores.
Uno ejemplo era el número de días de duración de un Curso; habría un rango
razonable de duraciones más allá cual nosotros quería no desear el número de días
a ser colocar. Ciertamente, nosotros quería
236 9 Exception
Handling
No quiero valores negativos, y dado que Java “ int ” El tipo no tiene signo, por lo
que no obtendríamos protección con solo usar el tipo de datos. En este ejemplo,
agregaremos algunos condicional código a el “ establecerNumeroDeDías ”
método eso voluntad explícitamente Lanzar una excepción Si el valor del
parámetro suministrado a es menos que 1 o más de 10 (por supuesto, podríamos
aplicar cualquier regla para un rango de valores que quisiéramos).
¿Qué tipo? de excepción ¿Deberíamos tirar? Java tiene muchas excepciones
Clases que atienden para varios tipos de excepción, pero el uno eso quería ser
mayoría adecuado Aquí estaría la IllegalArgumentException . En los ejemplos
anteriores, las excepciones se han lanzado automáticamente, pero en este caso,
debemos crear y lanzar explícitamente la excepción nosotros mismos, ya que la
máquina virtual Java no puede juzgar si un parámetro viola una regla de negocio.
En el cuerpo del método, podemos usar una declaración “ if ” que contenga
un “ throw ” para crear la excepción, si es necesario. La palabra clave “ throw ”
va seguida de un objeto IllegalArgumentException , creado mediante el
constructor. eso acepta a Cadena como a parámetro. Este parámetro es destinado a
ser Se utiliza para un mensaje de error. En la siguiente versión revisada del
método “ setNumberOfDays ” , un Excepción de argumento ilegal es arrojado si
el “ númeroDeDías ” El parámetro está fuera de rango. Observe la adición de la
anotación de Javadoc “ @throws ” en el bloque de comentarios.
IllegalArgumentException es una excepción no controlada, por lo que el
compilador no obligará al código del cliente a tener en cuenta que puede lanzarse .
Por lo tanto, la adición de un comentario de Javadoc es útil para los usuarios
potenciales del método.
/**
* @param numeroDeDías
* @lanza Excepción de argumento ilegal
*/
público vacío establecerNumeroDeDías ( int
numberOfDays ) lanza
IllegalArgumentException
{
si ( número de días < 1 || numeroDeDías > 10)
{
tirar nuevo IllegalArgumentException
( número de días) + " está fuera del
rango válido de 1 - 10");
}
demás
{
[Link] = numeroDeDias ;
}
}

La última pieza del rompecabezas está en el código del cliente que crea un
Curso y llama al “ establecerNumeroDeDías ” método. En este código, nosotros
intentar a colocar el número de días a “ 12 ” para activar deliberadamente la
excepción:
Inde 237
x

paquete
[Link] .chapter9;
clase pública CreateCourse
{
público estático vacío principal( Cadena[] argumentos )
{
intentar
{
Curso do = nuevo Curso( );
[Link] (12);
}
captura( Excepción de argumento ilegal mi)
{
[Link] ();
}
}
}

El producción de correr este programa es

[Link] : 12 es afuera
el rango válido de 1 - 10
en [Link]
([Link]) en
[Link](CreateCourse
.java:10)

Puede ver que el parámetro del mensaje de error del constructor de excepción
se imprime como parte del seguimiento de la pila.
Un problema ahora es que el constructor llama al método “ set ” , pero alguien
que crea un objeto Course no sabrá que se puede generar una
IllegalArgumentException . Podemos solucionar esto agregando la cláusula “
throws ” necesaria al constructor.
público Curso( Cadena nombre, entero días,
doble precio) lanza
IllegalArgumentException

Nuevamente, podemos agregar un “ @throws ” al comentario de Javadoc. Esto


simplemente lo deja claro a usuarios de el clase eso el parametrizado constructor
puede probablemente tirar Esta excepción.

9.5.1 Delegar Responsabilidad

Poder lanzar excepciones explícitamente, como hicimos en el ejemplo anterior, es


una forma muy útil de asegurar la lógica de nuestros programas porque significa
que si algo va equivocado en un solicitud eso es no a Java sistema error entonces
nosotros Todavía puede usar el incorporado excepción manejo mecanismo a señal
el error a eso parte del código que debe manejar el problema.
Los ejemplos utilizados hasta ahora en este capítulo simplemente ignoran
cualquier excepción lanzada, impresión el pila rastro y que lleva en. Sin
238 Inde
x
embargo, en real sistemas, nosotros

Common questions

Con tecnología de IA

Implementing an interface in Java means providing concrete implementations for all of its declared methods, allowing a class to adopt multiple types or sets of behaviors since multiple interfaces can be implemented. Extending a class, however, involves inheriting the implementation and state of a single superclass, which limits the class to one inheritance path. This affects class design as interfaces promote a more flexible design strategy by allowing role-based design and separation of concerns, while extending a class provides a single path of behavior and state inheritance .

With Java 8, default methods were introduced in interfaces to provide concrete implementations that can be optionally overridden by implementing classes. This allows for the evolution of interfaces without breaking existing implementations. Static methods in interfaces provide utility methods related to the interface's concept that can be invoked independently of any instance. Both default and static methods contribute to more flexible interface design, allowing additional functionalities to be added seamlessly and shared utility functions to be encapsulated within the interface .

Java differentiates between checked and unchecked exceptions to enforce robustness in applications. Checked exceptions are those that must be either handled using a 'try-catch' block or declared to be thrown in the method signature with 'throws'. This requirement forces the programmer to address potential disruptions in program flow. Unchecked exceptions, such as runtime exceptions, do not have this requirement and can be caught optionally. Robust application design involves anticipating potential exceptions and implementing appropriate handlers or notifications to ensure graceful degradation of functionality or application failure .

Interfaces in Java provide a way to achieve multiple inheritance by allowing a class to implement multiple interfaces, thus adopting multiple behaviors. Unlike classes, a class in Java can only inherit from one superclass, but by implementing various interfaces, a class can incorporate multiple functionalities and represent multiple roles. This approach allows for better flexibility and cross-cutting concerns to be addressed that would otherwise not neatly fit into a single inheritance hierarchy .

Polymorphism and interface implementation facilitate diverse but consistently handled components by allowing objects of different classes to be treated as instances of the same interface type. This enables a consistent method call structure across various object types, which may belong to different class hierarchies, yet share a common behavior or responsibility as defined by the interface. By relying on interfaces, a system can be extended and modified with minimal disruption to its existing architecture, as new classes can be integrated seamlessly if they adhere to the same interface .

Dynamic binding in Java refers to the process where the method to be executed is determined at runtime rather than compile time. This is particularly utilized in polymorphism, where a superclass reference can point to a subclass object, and the appropriate overridden method of the subclass is executed. Interfaces enhance this capability as they allow different classes to implement methods from the interface, enabling objects to be handled more flexibly. An object can be referred to through different interfaces it implements, showcasing different perspectives or roles in a program .

Handling multiple exceptions in Java can be efficiently managed by using a single try block followed by multiple catch blocks, each handling a different type of exception. This structure allows for concise error handling and greater clarity in understanding the program's fault tolerance capabilities. It simplifies maintenance as changes in exception handling strategy can be localized, making it easier to adapt the code to handle new exceptions or to refine responses without extensive refactoring .

Using action-based naming conventions for interfaces, such as ending in 'able,' emphasizes the action or capability that a class can perform. This convention makes it immediately clear what a class implementing the interface is capable of doing, thus improving code readability and maintaining a clear distinction between classes and the behaviors they can perform. It reflects a design where the emphasis is on the capabilities or actions rather than on the class hierarchy, promoting an understanding of the class role in a larger system context .

Default methods in interfaces allow for the addition of new behavior without breaking existing implementations. However, they can lead to ambiguities if a class implements multiple interfaces that define default methods with the same signature. To mitigate such issues, developers must explicitly override conflicting methods or use interface-specific syntax to distinguish between them. Moreover, careful design and documentation are required to ensure that the introduction of default methods does not introduce unexpected behavior into the system .

Introducing static methods in interfaces has shifted some of the traditional utility functions from separate utility classes into interfaces directly associated with the behavior or concept in question. This helps encapsulate related functionality within the interface, promoting cohesive design patterns. However, it may also blur the separation between interface definitions and their implementations, potentially complicating design principles if not managed properly. The impact is mostly positive as it centrally locates auxiliary methods related to specific interface domains within their defining interfaces, thus reinforcing logical design abstraction .

También podría gustarte