Skip to main content

CLASES E INTERFACES ABSTRACTAS - CAPITULO 13

CLASES E INTERFACES ABSTRACTAS

Una superclase define el comportamiento común de las subclases relacionadas. Se puede usar una interfaz para definir el comportamiento común de las clases (incluidas las clases no relacionadas).
Puede usar el método java.util.Arrays.sort para ordenar una matriz de números o cadenas.

Clases abstractas

No se puede usar una clase abstracta para crear objetos. Una clase abstracta puede contener métodos abstractos, que se implementan en subclases concretas. En la jerarquía de herencia, las clases se vuelven más específicas y concretas con cada nueva subclase. Si pasa de una subclase a una superclase, las clases se vuelven más generales y menos específicas. El diseño de la clase debe garantizar que una superclase contenga características comunes de sus subclases. A veces, una superclase es tan abstracta que no se puede usar para crear instancias específicas. Dicha clase se conoce como una clase abstracta.

Las clases abstractas son como las clases regulares, pero no puede crear instancias de clases abstractas utilizando el nuevo operador. Se define un método abstracto sin implementación. Su implementación es proporcionada por las subclases. Una clase que contiene métodos abstractos debe definirse como abstracta. El constructor en la clase abstracta se define como protegido, porque solo lo usan las subclases. Cuando crea una instancia de una subclase concreta, se invoca al constructor de su superclase para inicializar los campos de datos definidos en la superclase

Por qué métodos abstractos?
Quizás se pregunte qué ventaja se obtiene al definir los métodos getArea () y getPerimeter () como abstractos en la clase GeometricObject. El ejemplo en el Listado 13.4 muestra los beneficios de definirlos en la clase GeometricObject. El programa crea dos objetos geométricos, un círculo y un rectángulo, invoca el método equalArea para verificar si tienen áreas iguales e invoca el método displayGeometricObject para mostrarlos.

Puntos interesantes sobre las clases abstractas
Vale la pena señalar los siguientes puntos sobre las clases abstractas:
   Un método abstracto no puede estar contenido en una clase no abstracta. Si una subclase de una superclase abstracta no implementa todos los métodos abstractos, la subclase debe definirse como abstracta. En otras palabras, en una subclase no abstracta extendida desde una clase abstracta, todos los métodos abstractos deben implementarse. También tenga en cuenta que los métodos abstractos no son estáticos.
   No se puede crear una instancia de una clase abstracta utilizando el nuevo operador, pero aún puede definir sus constructores, que se invocan en los constructores de sus subclases. Por ejemplo, los constructores de GeometricObject se invocan en la clase Circle y la clase Rectángulo.
   Una clase que contiene métodos abstractos debe ser abstracta. Sin embargo, es posible definir una clase abstracta que no contenga ningún método abstracto. En este caso, no puede crear instancias de la clase utilizando el nuevo operador. Esta clase se usa como una clase base para definir subclases.
   Una subclase puede anular un método de su superclase para definirlo como abstracto. Esto es muy inusual, pero es útil cuando la implementación del método en la superclase deja de ser válida en la subclase. En este caso, la subclase debe definirse como abstracta.
   Una subclase puede ser abstracta incluso si su superclase es concreta. Por ejemplo, la clase Object es concreta, pero sus subclases, como GeometricObject, pueden ser abstractas.
   No puede crear una instancia a partir de una clase abstracta utilizando el nuevo operador, pero se puede utilizar una clase abstracta como tipo de datos. Por lo tanto, la siguiente declaración, que crea una matriz cuyos elementos son del tipo GeometricObject, es correcta.

GeometricObject[] objects = new GeometricObject[10];

Interfaces

Una interfaz es una construcción de clase que contiene solo constantes y métodos abstractos. En muchos sentidos, una interfaz es similar a una clase abstracta, pero su intención es especificar un comportamiento común para objetos de clases relacionadas o clases no relacionadas. Por ejemplo, usando las interfaces apropiadas, puede especificar que los objetos sean comparables, comestibles y / o clonables. Para distinguir una interfaz de una clase, Java utiliza la siguiente sintaxis para definir una interfaz:

modifier interface InterfaceName {
/** Constant declarations */
/** Abstract method signatures */ }

Ejemplo de una interfaz:
public interface Edible {
 /** Describe how to eat */
public abstract String howToEat(); }

Una interfaz se trata como una clase especial en Java. Cada interfaz se compila en un archivo de bytecode separado, como una clase normal. Puede usar una interfaz más o menos de la misma manera que usa una clase abstracta. Por ejemplo, puede usar una interfaz como tipo de datos para una variable de referencia, como resultado de la conversión, etc. Al igual que con una clase abstracta, no puede crear una instancia desde una interfaz utilizando el nuevo operador. Puede usar la interfaz comestible para especificar si un objeto es comestible. Esto se logra dejando que la clase para el objeto implemente esta interfaz utilizando la palabra clave implements.

La interfaz comparable

La interfaz comparable define el método compareTo para comparar objetos. Suponga que desea diseñar un método genérico para encontrar el mayor de dos objetos del mismo tipo, como dos estudiantes, dos fechas, dos círculos, dos rectángulos o dos cuadrados. Para lograr esto, los dos objetos deben ser comparables, por lo que el comportamiento común de los objetos debe ser comparable. Java proporciona la interfaz comparable para este propósito. La interfaz se define de la siguiente manera:
                                                                                                                                               
// Interface for comparing objects, defined in java.lang
package java.lang;
public interface Comparable<E> {
public int compareTo(E o);
}

El método compareTo determina el orden de este objeto con el objeto especificado o y devuelve un entero negativo, cero o un entero positivo si este objeto es menor, igual o mayor que o. La interfaz comparable es una interfaz genérica. El tipo genérico E se reemplaza por un tipo concreto al implementar esta interfaz. Muchas clases en la biblioteca Java implementan Comparable para definir un orden natural para los objetos.

La interfaz clonable

La interfaz clonable especifica que un objeto puede ser clonado. A menudo es deseable crear una copia de un objeto. Para hacer esto, debe usar el método de clonación y comprender la interfaz clonable. Una interfaz contiene constantes y métodos abstractos, pero la interfaz clonable es un caso especial. La interfaz clonable en el paquete java.lang se define de la siguiente manera:

package java.lang;
public interface Cloneable {
}

Esta interfaz está vacía. Una interfaz con un cuerpo vacío se denomina interfaz de marcador. Una interfaz de marcador no contiene constantes ni métodos. Se utiliza para denotar que una clase posee ciertas propiedades deseables. Una clase que implementa la interfaz Cloneable se marca clonable, y sus objetos se pueden clonar utilizando el método clone () definido en la clase Object. Muchas clases en la biblioteca de Java (por ejemplo, Fecha, Calendario y ArrayList) implementan Cloneable.

Interfaces vs Clases abstractas

Una clase puede implementar múltiples interfaces, pero solo puede extender una superclase. Una interfaz se puede usar más o menos de la misma manera que una clase abstracta, pero definir una interfaz es diferente de definir una clase abstracta.

Java permite solo una única herencia para la extensión de clase, pero permite múltiples extensiones para las interfaces. Por ejemplo:
public class NewClass extends BaseClass
     implements Interface1, ..., InterfaceN {  ...
}

Una interfaz puede heredar otras interfaces usando la palabra clave extend. Dicha interfaz se llama subinterfaz. Por ejemplo, NewInterface en el siguiente código es una subinterfaz de Interface1,. . . y InterfaceN.


public interface NewInterface extends Interface1, ... , InterfaceN {
// constants and abstract methods
}

Una clase que implementa NewInterface debe implementar los métodos abstractos definidos en NewInterface, Interface1,. . . y InterfaceN. Una interfaz puede extender otras interfaces pero no clases. Una clase puede extender su superclase e implementar múltiples interfaces. Todas las clases comparten una sola raíz, la clase Object, pero no hay una sola raíz para las interfaces. Al igual que una clase, una interfaz también define un tipo. Una variable de un tipo de interfaz puede hacer referencia a cualquier instancia de la clase que implemente la interfaz. Si una clase implementa una interfaz, la interfaz es como una superclase para la clase. Puede usar una interfaz como tipo de datos y emitir una variable de un tipo de interfaz a su subclase, y viceversa.

Pautas de diseño de clase:
Las pautas de diseño de clase son útiles para diseñar clases de sonido. Aprendió a diseñar clases a partir de los dos ejemplos anteriores y de muchos otros ejemplos en los capítulos anteriores. Esta sección resume algunas de las pautas.

Cohesión:
Una clase debería describir una sola entidad, y todas las operaciones de la clase deberían encajar lógicamente para apoyar un propósito coherente. Puede usar una clase para estudiantes, por ejemplo, pero no debe combinar estudiantes y personal en la misma clase, porque los estudiantes y el personal son entidades diferentes. Una sola entidad con muchas responsabilidades puede dividirse en varias clases para separar las responsabilidades. Las clases String, StringBuilder y StringBuffer tratan todas las cadenas, por ejemplo, pero tienen diferentes responsabilidades. La clase String trata con cadenas inmutables, la clase StringBuilder es para crear cadenas mutables y la clase StringBuffer es similar a StringBuilder, excepto que StringBuffer contiene métodos sincronizados para actualizar cadenas.

Consistencia:
Siga el estilo de programación estándar de Java y las convenciones de nombres. Elija nombres informativos para clases, campos de datos y métodos. Un estilo popular es colocar la declaración de datos antes del constructor y colocar los constructores antes que los métodos. Haz que los nombres sean consistentes. No es una buena práctica elegir nombres diferentes para operaciones similares. Por ejemplo, el método length () devuelve el tamaño de un String, un StringBuilder y un StringBuffer. Sería inconsistente si se usaran diferentes nombres para este método en estas clases. En general, siempre debe proporcionar un constructor público sin argumentos para construir una instancia predeterminada. Si una clase no admite un constructor sin argumentos, documente el motivo. Si no se definen explícitamente constructores, se supone un constructor público sin argumentos con un cuerpo vacío. Si desea evitar que los usuarios creen un objeto para una clase, puede declarar un constructor privado en la clase, como es el caso de la clase Math.

Encapsulación:
Una clase debe usar el modificador privado para ocultar sus datos del acceso directo de los clientes. Esto hace que la clase sea fácil de mantener. Proporcione un método getter solo si desea que el campo de datos sea legible, y proporcione un método setter solo si desea que el campo de datos sea actualizable. Por ejemplo, la clase Rational proporciona un método getter para numerador y denominador, pero no un método setter, porque un objeto Rational es inmutable.

Claridad:
La cohesión, la consistencia y la encapsulación son buenas pautas para lograr la claridad del diseño. Además, una clase debe tener un contrato claro que sea fácil de explicar y fácil de entender. Los usuarios pueden incorporar clases en muchas combinaciones, órdenes y entornos diferentes. Por lo tanto, debe diseñar una clase que no imponga restricciones sobre cómo o cuándo puede usarla el usuario, diseñar las propiedades de una manera que le permita establecerlas en cualquier orden y con cualquier combinación de valores, y diseñar métodos que funcionen independientemente de su orden de ocurrencia.

Completo:
Las clases están diseñadas para ser utilizadas por muchos clientes diferentes. Para ser útil en una amplia gama de aplicaciones, una clase debe proporcionar una variedad de formas de personalización a través de propiedades y métodos. Por ejemplo, la clase String contiene más de 40 métodos que son útiles para una variedad de aplicaciones.

Instancia vs Estática:
Una variable o método que depende de una instancia específica de la clase debe ser una variable o método de instancia. Una variable compartida por todas las instancias de una clase debe declararse estática. Por ejemplo, la variable numberOfObjects en CircleWithPrivateDataFields en el Listado 9.8 es compartida por todos los objetos de la clase CircleWithPrivateDataFields y, por lo tanto, se declara estática. Un método que no depende de una instancia específica debe definirse como un método estático. Por ejemplo, el método getNumberOfObjects () en CircleWithPrivateDataFields no está vinculado a ninguna instancia específica y, por lo tanto, se define como un método estático. Siempre haga referencia a variables y métodos estáticos desde un nombre de clase (en lugar de una variable de referencia) para mejorar la legibilidad y evitar errores. No pase un parámetro de un constructor para inicializar un campo de datos estático. Es mejor usar un método de establecimiento para cambiar el campo de datos estáticos.

Instancia y estática son partes integrales de la programación orientada a objetos. Un campo o método de datos es instancia o estático. No pase por alto por error campos o métodos de datos estáticos. Es un error de diseño común definir un método de instancia que debería haber sido estático

 Herencia vs Agregación:
La diferencia entre herencia y agregación es la diferencia entre una relación is-a y has-a. Por ejemplo, una manzana es una fruta; por lo tanto, usaría la herencia para modelar la relación entre las clases Apple y Fruit. Una persona tiene un nombre; por lo tanto, usaría la agregación para modelar la relación entre las clases Persona y Nombre.

Interfaces vs Clases abstractas:
Ambas interfaces y clases abstractas se pueden utilizar para especificar un comportamiento común para los objetos. ¿Cómo decides si usar una interfaz o una clase? En general, una relación es-una fuerte que describe claramente una relación padre-hijo debe modelarse utilizando clases. Por ejemplo, dado que una naranja es una fruta, su relación debe modelarse utilizando la herencia de clase. Una relación débil de es-una, también conocida como una relación de tipo, indica que un objeto posee cierta propiedad. Una relación débil de is-a se puede modelar usando interfaces. Por ejemplo, todas las cadenas son comparables, por lo que la clase String implementa la interfaz Comparable. Un círculo o un rectángulo es un objeto geométrico, por lo que Circle puede diseñarse como una subclase de GeometricObject. Los círculos son diferentes y comparables en función de sus radios, por lo que Circle puede implementar la interfaz Comparable. Las interfaces son más flexibles que las clases abstractas, porque una subclase solo puede extender una superclase pero puede implementar cualquier cantidad de interfaces. Sin embargo, las interfaces no pueden contener métodos concretos. Las virtudes de las interfaces y las clases abstractas se pueden combinar creando una interfaz con una clase abstracta que la implemente. Luego puede usar la interfaz o la clase abstracta, lo que sea conveniente.






                                                                    Bibliografia
Y. Daniel Liang. (2011). INTRODUCTION TO JAVA PROGRAMMING COMPREHENSIVE VERSION. USA: Armstrong Atlantic State University.


Comments

Popular posts from this blog

Recorridos del arbol binario en c

Recorridos de arboles binarios:  Los recorridos en arboles binarios se encargar de imprimir cada nodo del árbol, desde su raíz o nodo padre, hasta todas su hojas o nodos hijos. Existen 3 tipos de recorridos: Preorden: Realiza estos pasos recursivamente: Imprime la raíz. Atraviesa e imprime los nodos del sub-árbol izquierdo. Atraviesa e imprime los nodos del sub-árbol derecho.     Inorden: Realiza estos paso recursivamente.  Atraviesa e imprime los nodos del sub-árbol izquierdo.  Imprime la raíz.  Atraviesa e imprime los nodos del sub-árbol derecho.   Postorden: Realiza estos pasos recursivamente:   Atraviesa e imprime los nodos del sub-árbol izquierdo.  Atraviesa e imprime los nodos del sub-árbol derecho.   Imprime la raíz.  Bibliografia Ruiz E. (2013). ejemplos recorridos arboles binarios. 18 de setiembre del 2019, de ingenieria de software y negocios inteligentes Sitio web...

Ciclos - Capitulo 5

Introducción Se puede usar un bucle para indicarle a un programa que ejecute sentencias repetidamente. Suponga que necesita mostrar una cadena (por ejemplo, ¡Bienvenido a Java!) Cientos de veces. Sería tedioso tener que escribir la siguiente declaración cien veces:  Entonces, ¿cómo resuelves este problema? Java proporciona una construcción poderosa llamada bucle que controla cuántas veces se realiza una operación o una secuencia de operaciones en sucesión. Usando una declaración de bucle, simplemente le dice a la computadora que muestre una cadena cien veces sin tener que codificar la declaración de impresión cien veces, de la siguiente manera: Ciclo While Un ciclo while ejecuta declaraciones repetidamente mientras la condición es verdadera. La figura 5.1a muestra el diagrama de flujo del ciclo while. La parte del ciclo que contiene las declaraciones que se repetirán se llama cuerpo del ciclo. Una ejecución única de un cuerpo de bucle se conoce como una i...