Clase abstracta en Java

¿Qué es una “clase abstracta” en Java?

Una clase abstracta es una clase que no puede ser instanciada. Se usa una clase abstracta al crear una subclase heredada que se puede instanciar. Una clase abstracta hace algunas cosas para la subclase heredada:

  1. Defina métodos que puedan ser utilizados por la subclase heredada.
  2. Definir métodos abstractos que la subclase heredada debe implementar.
  3. Proporcione una interfaz común que permita intercambiar la subclase con todas las demás subclases.

Aquí hay un ejemplo:

abstract public class AbstractClass { abstract public void abstractMethod(); public void implementedMethod() { System.out.print("implementedMethod()"); } final public void finalMethod() { System.out.print("finalMethod()"); } } 

Tenga en cuenta que “abstractMethod ()” no tiene ningún cuerpo de método. Debido a esto, no puedes hacer lo siguiente:

 public class ImplementingClass extends AbstractClass { // ERROR! } 

¡No hay ningún método que implemente abstractMethod() ! Así que no hay forma de que la JVM sepa lo que se supone que debe hacer cuando obtiene algo como la new ImplementingClass().abstractMethod() .

Aquí hay una clase de ImplementingClass correcta.

 public class ImplementingClass extends AbstractClass { public void abstractMethod() { System.out.print("abstractMethod()"); } } 

Tenga en cuenta que no tiene que definir implementedMethod() o finalMethod() . Ya fueron definidos por AbstractClass .

Aquí hay otra clase de ImplementingClass correcta.

 public class ImplementingClass extends AbstractClass { public void abstractMethod() { System.out.print("abstractMethod()"); } public void implementedMethod() { System.out.print("Overridden!"); } } 

En este caso, ha reemplazado el método implementedMethod() .

Sin embargo, debido a la palabra clave final , lo siguiente no es posible.

 public class ImplementingClass extends AbstractClass { public void abstractMethod() { System.out.print("abstractMethod()"); } public void implementedMethod() { System.out.print("Overridden!"); } public void finalMethod() { System.out.print("ERROR!"); } } 

No puede hacer esto porque la implementación de finalMethod() en AbstractClass está marcada como la implementación final de finalMethod() final finalMethod() : no se permitirán otras implementaciones.

Ahora también puedes implementar una clase abstracta dos veces:

 public class ImplementingClass extends AbstractClass { public void abstractMethod() { System.out.print("abstractMethod()"); } public void implementedMethod() { System.out.print("Overridden!"); } } // In a separate file. public class SecondImplementingClass extends AbstractClass { public void abstractMethod() { System.out.print("second abstractMethod()"); } } 

Ahora en algún lugar podrías escribir otro método.

 public tryItOut() { ImplementingClass a = new ImplementingClass(); AbstractClass b = new ImplementingClass(); a.abstractMethod(); // prints "abstractMethod()" a.implementedMethod(); // prints "Overridden!" <-- same a.finalMethod(); // prints "finalMethod()" b.abstractMethod(); // prints "abstractMethod()" b.implementedMethod(); // prints "Overridden!" <-- same b.finalMethod(); // prints "finalMethod()" SecondImplementingClass c = new SecondImplementingClass(); AbstractClass d = new SecondImplementingClass(); c.abstractMethod(); // prints "second abstractMethod()" c.implementedMethod(); // prints "implementedMethod()" c.finalMethod(); // prints "finalMethod()" d.abstractMethod(); // prints "second abstractMethod()" d.implementedMethod(); // prints "implementedMethod()" d.finalMethod(); // prints "finalMethod()" } 

Tenga en cuenta que aunque declaramos b un tipo AbstractClass , muestra "Overriden!" . Esto se debe a que el objeto que instanciamos era en realidad una ImplementingClass , cuyo implementedMethod() está, por supuesto, anulado. (Puede haber visto esto referido como polymorphism).

Si deseamos acceder a un miembro específico de una determinada subclase, primero debemos enviarlo a esa subclase:

 // Say ImplementingClass also contains uniqueMethod() // To access it, we use a cast to tell the runtime which type the object is AbstractClass b = new ImplementingClass(); ((ImplementingClass)b).uniqueMethod(); 

Por último, no puede hacer lo siguiente:

 public class ImplementingClass extends AbstractClass, SomeOtherAbstractClass { ... // implementation } 

Solo una clase se puede extender a la vez. Si necesita extender múltiples clases, tienen que ser interfaces. Puedes hacerlo:

 public class ImplementingClass extends AbstractClass implements InterfaceA, InterfaceB { ... // implementation } 

Aquí hay una interfaz de ejemplo:

 interface InterfaceA { void interfaceMethod(); } 

Esto es básicamente lo mismo que:

 abstract public class InterfaceA { abstract public void interfaceMethod(); } 

La única diferencia es que la segunda forma no le permite al comstackdor saber que en realidad es una interfaz. Esto puede ser útil si desea que las personas solo implementen su interfaz y no otras. Sin embargo, como regla general para principiantes, si su clase abstracta solo tiene métodos abstractos, probablemente deba convertirla en una interfaz.

Lo siguiente es ilegal:

 interface InterfaceB { void interfaceMethod() { System.out.print("ERROR!"); } } 

No puede implementar métodos en una interfaz. Esto significa que si implementa dos interfaces diferentes, los diferentes métodos en esas interfaces no pueden colisionar. Dado que todos los métodos en una interfaz son abstractos, debe implementar el método, y dado que su método es la única implementación en el árbol de herencia, el comstackdor sabe que debe usar su método.

Una clase de Java se vuelve abstracta bajo las siguientes condiciones:

1. Al menos uno de los métodos está marcado como abstracto:

 public abstract void myMethod() 

En ese caso, el comstackdor te obliga a marcar toda la clase como abstracta.

2. La clase está marcada como abstracta:

 abstract class MyClass 

Como ya se dijo: si tiene un método abstracto, el comstackdor lo obliga a marcar toda la clase como abstracto. Pero incluso si no tiene ningún método abstracto, puede marcar la clase como abstracta.

Uso común:

Un uso común de las clases abstractas es proporcionar un esquema de una clase similar a una interfaz. Pero a diferencia de una interfaz, ya puede proporcionar funcionalidad, es decir, algunas partes de la clase se implementan y algunas partes se describen con una statement de método. (“abstracto”)

No se puede crear una instancia de una clase abstracta, pero puede crear una clase concreta basada en una clase abstracta, que luego se puede instanciar. Para hacerlo, debe heredar de la clase abstracta y anular los métodos abstractos, es decir, implementarlos.

Una clase que se declara utilizando la palabra clave abstracta se conoce como abstract class . La abstracción es un proceso de ocultar los detalles de implementación de datos y mostrar solo la funcionalidad para el usuario. La abstracción le permite concentrarse en lo que hace el objeto en lugar de cómo lo hace.

Lo principal de la clase abstracta

  • Una clase abstracta puede o no contener métodos abstractos. Puede haber métodos no abstractos.

    Un método abstracto es un método que se declara sin una implementación (sin llaves y seguido de un punto y coma), como este:

    ej .: abstract void moveTo(double deltaX, double deltaY);

  • Si una clase tiene al menos un método abstracto, entonces esa clase debe ser abstracta

  • Las clases abstractas no se pueden crear instancias (no se permite crear objetos de clase abstracta)

  • Para usar una clase abstracta, debes heredarla de otra clase. Proporcione implementaciones a todos los métodos abstractos en él.

  • Si hereda una clase abstracta, debe proporcionar implementaciones a todos los métodos abstractos.

Declarar clase abstracta Especificar palabra clave abstract antes de la clase durante la statement lo hace abstracto. Echa un vistazo al código a continuación:

 abstract class AbstractDemo{ } 

Declarar el método abstracto Especificar abstract palabra clave abstract antes del método durante la statement lo hace abstracto. Eche un vistazo al código a continuación,

 abstract void moveTo();//no body 

Por qué necesitamos abstraer clases

En una aplicación de dibujo orientada a objetos, puede dibujar círculos, rectangularjs, líneas, curvas de Bezier y muchos otros objetos gráficos. Todos estos objetos tienen ciertos estados (por ejemplo, posición, orientación, color de línea, color de relleno) y comportamientos (por ejemplo, mover a, girar, cambiar el tamaño, dibujar) en común. Algunos de estos estados y comportamientos son los mismos para todos los objetos gráficos (por ejemplo: color de relleno, posición y mover a). Otros requieren una implementación diferente (por ej .: cambiar el tamaño o dibujar). Todos los objetos gráficos deben ser capaces de dibujar o cambiar su tamaño, simplemente difieren en cómo lo hacen.

Esta es una situación perfecta para una superclase abstracta. Puede aprovechar las similitudes y declarar todos los objetos gráficos para heredar del mismo objeto principal abstracto (por ejemplo, GraphicObject ) como se muestra en la figura siguiente. enter image description here

En primer lugar, declara una clase abstracta, GraphicObject , para proporcionar variables miembro y métodos que todas las subclases comparten por completo, como la posición actual y el método moveTo. GraphicObject también declaró métodos abstractos, como dibujar o cambiar el tamaño, que deben ser implementados por todas las subclases, pero deben implementarse de diferentes maneras. La clase GraphicObject puede verse más o menos así:

 abstract class GraphicObject { void moveTo(int x, int y) { // Inside this method we have to change the position of the graphic // object according to x,y // This is the same in every GraphicObject. Then we can implement here. } abstract void draw(); // But every GraphicObject drawing case is // unique, not common. Then we have to create that // case inside each class. Then create these // methods as abstract abstract void resize(); } 

Uso del método abstracto en subclases Cada subclases no abstractas de GraphicObject , como Circle y Rectangle , deben proporcionar implementaciones para los métodos de draw y resize .

 class Circle extends GraphicObject { void draw() { //Add to some implementation here } void resize() { //Add to some implementation here } } class Rectangle extends GraphicObject { void draw() { //Add to some implementation here } void resize() { //Add to some implementation here } } 

Dentro del método main puedes llamar a todos los métodos como este:

 public static void main(String args[]){ GraphicObject c = new Circle(); c.draw(); c.resize(); c.moveTo(4,5); } 

Formas de lograr la abstracción en Java

Hay dos formas de lograr la abstracción en java

  • Clase abstracta (0 a 100%)
  • Interfaz (100%)

Clase abstracta con constructores, miembros de datos, métodos, etc.

 abstract class GraphicObject { GraphicObject (){ System.out.println("GraphicObject is created"); } void moveTo(int y, int x) { System.out.println("Change position according to "+ x+ " and " + y); } abstract void draw(); } class Circle extends GraphicObject { void draw() { System.out.println("Draw the Circle"); } } class TestAbstract { public static void main(String args[]){ GraphicObject grObj = new Circle (); grObj.draw(); grObj.moveTo(4,6); } } 

Salida:

 GraphicObject is created Draw the Circle Change position according to 6 and 4 

Recuerde dos reglas:

  • Si la clase tiene pocos métodos abstractos y pocos métodos concretos, declararlo como una clase abstract .

  • Si la clase solo tiene métodos abstractos, declararlo como una interface .

Referencias

  • TutorialsPoint – Abstracción de Java
  • BeginnersBook – Método de la clase abstracta de Java
  • Documentos de Java: métodos y clases abstractos
  • JavaPoint – Clase abstracta en Java

Es una clase que no se puede instanciar y obliga a implementar clases para implementar, posiblemente, métodos abstractos que se describen.

De la documentación del oracle

Métodos abstractos y clases:

Una clase abstracta es una clase que se declara abstracta; puede o no incluir métodos abstractos

Las clases abstractas no se pueden crear instancias, pero se pueden subclasificar

Un método abstracto es un método que se declara sin una implementación (sin llaves y seguido de un punto y coma), como este:

 abstract void moveTo(double deltaX, double deltaY); 

Si una clase incluye métodos abstractos, entonces la clase misma debe declararse abstracta, como en:

 public abstract class GraphicObject { // declare fields // declare nonabstract methods abstract void draw(); } 

Cuando se subclasifica una clase abstracta, la subclase generalmente proporciona implementaciones para todos los métodos abstractos en su clase principal. Sin embargo, si no lo hace, entonces la subclase también debe declararse abstracta .

Dado que las abstract classes e interfaces abstract classes están relacionadas, eche un vistazo a las siguientes preguntas SE:

¿Cuál es la diferencia entre una interfaz y una clase abstracta?

¿Cómo debería haber explicado la diferencia entre una interfaz y una clase abstracta?

Obtenga sus respuestas aquí:

Clase abstracta vs Interfaz en Java

¿Puede una clase abstracta tener un método final?

Por cierto, esas son preguntas que preguntaste recientemente. Piensa en una nueva pregunta para construir reputación …

Editar:

Acabo de darme cuenta de que los pósters de esta y las preguntas a las que se hace referencia tienen el mismo o al menos similar nombre, pero la identificación del usuario siempre es diferente. Entonces, o bien, hay un problema técnico, que Keyur tiene problemas para iniciar sesión de nuevo y encontrar las respuestas a sus preguntas o este es un tipo de juego para entretener a la comunidad SO;)

Simplemente hablando, puede pensar en una clase abstracta como una interfaz con un poco más de capacidades.

No puede crear una instancia de una interfaz, que también se aplica a una clase abstracta.

En su interfaz, puede definir los encabezados de método y TODOS los implementadores están obligados a implementarlos todos . En una clase abstracta también puede definir los encabezados de sus métodos, pero aquí, con la diferencia de la interfaz, también puede definir el cuerpo (generalmente una implementación predeterminada) del método. Además cuando otras clases se extienden (nota, no implementa y por lo tanto también puedes tener solo una clase abstracta por clase) tu clase abstracta, no están forzadas a implementar todos tus métodos de tu clase abstracta, a menos que hayas especificado un método abstracto ( en tal caso, funciona como para interfaces, no puede definir el cuerpo del método).

 public abstract class MyAbstractClass{ public abstract void DoSomething(); } 

De lo contrario, para los métodos normales de una clase abstracta, los “herederos” pueden usar el comportamiento predeterminado o anularlo, como de costumbre.

Ejemplo:

 public abstract class MyAbstractClass{ public int CalculateCost(int amount){ //do some default calculations //this can be overriden by subclasses if needed } //this MUST be implemented by subclasses public abstract void DoSomething(); } 

Pequeña adición a todos estos mensajes.

A veces puede querer declarar una clase y aún así no saber cómo definir todos los métodos que pertenecen a esa clase. Por ejemplo, puede declarar una clase llamada Writer e incluir en ella un método miembro llamado write () . Sin embargo, no sabes cómo codificar write () porque es diferente para cada tipo de dispositivos Writer. Por supuesto, planea manejar esto al derivar la subclase Writer, como Impresora, Disco, Red y Consola.

Una clase abstracta no se puede crear una instancia directa, sino que se debe derivar para poder usarla. Una clase DEBE ser abstracta si contiene métodos abstractos: ya sea directamente

 abstract class Foo { abstract void someMethod(); } 

o indirectamente

 interface IFoo { void someMethod(); } abstract class Foo2 implements IFoo { } 

Sin embargo, una clase puede ser abstracta sin contener métodos abstractos. Es una forma de evitar la instalación directa, por ejemplo

 abstract class Foo3 { } class Bar extends Foo3 { } Foo3 myVar = new Foo3(); // illegal! class is abstract Foo3 myVar = new Bar(); // allowed! 

El último estilo de clases abstractas se puede usar para crear clases “tipo interfaz”. A diferencia de las interfaces, una clase abstracta puede contener métodos no abstractos y variables de instancia. Puede usar esto para proporcionar alguna funcionalidad básica para extender clases.

Otro patrón frecuente es implementar la funcionalidad principal en la clase abstracta y definir parte del algoritmo en un método abstracto para ser implementado por una clase extendida. Estúpido ejemplo:

 abstract class Processor { protected abstract int[] filterInput(int[] unfiltered); public int process(int[] values) { int[] filtered = filterInput(values); // do something with filtered input } } class EvenValues extends Processor { protected int[] filterInput(int[] unfiltered) { // remove odd numbers } } class OddValues extends Processor { protected int[] filterInput(int[] unfiltered) { // remove even numbers } } 

Solución – clase base (resumen)

 public abstract class Place { String Name; String Postcode; String County; String Area; Place () { } public static Place make(String Incoming) { if (Incoming.length() < 61) return (null); String Name = (Incoming.substring(4,26)).trim(); String County = (Incoming.substring(27,48)).trim(); String Postcode = (Incoming.substring(48,61)).trim(); String Area = (Incoming.substring(61)).trim(); Place created; if (Name.equalsIgnoreCase(Area)) { created = new Area(Area,County,Postcode); } else { created = new District(Name,County,Postcode,Area); } return (created); } public String getName() { return (Name); } public String getPostcode() { return (Postcode); } public String getCounty() { return (County); } public abstract String getArea(); } 

Clase que puede tener tanto métodos concretos como no concretos, es decir, con cuerpo y sin cuerpo. Los métodos 1 sin implementación deben contener palabra clave ‘abstracta’ 2: la clase abstracta no se puede instanciar

Una clase abstracta es una clase que se declara abstracta; puede incluir o no métodos abstractos. Las clases abstractas no se pueden crear instancias, pero se pueden subclasificar.

En otras palabras, una clase declarada con palabra clave abstracta se conoce como clase abstracta en Java. Puede tener métodos abstractos (método sin cuerpo) y no abstractos (método con cuerpo).

Nota importante: – Las clases abstractas no se pueden usar para crear instancias de objetos, sino que se pueden usar para crear referencias de objetos, porque el enfoque de Java para el polymorphism en tiempo de ejecución se implementa mediante el uso de referencias de superclase. Por lo tanto, debe ser posible crear una referencia a una clase abstracta para que pueda usarse para apuntar a un objeto de subclase. Verá esta característica en el siguiente ejemplo

 abstract class Bike{ abstract void run(); } class Honda4 extends Bike{ void run(){ System.out.println("running safely.."); } public static void main(String args[]){ Bike obj = new Honda4(); obj.run(); } } 

Miembros de la clase

Una clase abstracta puede tener campos estáticos y métodos estáticos. Puede usar estos miembros estáticos con una referencia de clase (por ejemplo, AbstractClass.staticMethod ()) como lo haría con cualquier otra clase.

No olvide esto

Una clase abstracta es una que no se implementa por completo, pero proporciona algo así como un modelo para las subclases. Se puede implementar parcialmente porque contiene métodos concretos completamente definidos, pero también puede contener métodos abstractos. Estos son métodos con una firma pero sin cuerpo de método. Cualquier subclase debe definir un cuerpo para cada método abstracto, de lo contrario también debe declararse abstracto. Debido a que las clases abstractas no se pueden crear instancias, se deben extender al menos una subclase para poder ser utilizadas. Piense en la clase abstracta como la clase genérica, y las subclases están ahí para completar la información faltante.