¿Qué es una "clase abstracta" en Java?
¿Qué es una "clase abstracta" en Java?
Respuestas:
Una clase abstracta es una clase que no puede ser instanciada. Una clase abstracta se usa creando una subclase heredada que se puede instanciar. Una clase abstracta hace algunas cosas para la subclase de herencia:
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 puede hacer lo siguiente:
public class ImplementingClass extends AbstractClass
{
// ERROR!
}
¡No hay ningún método que implemente abstractMethod()
! Por lo tanto, no hay forma de que la JVM sepa qué se supone que debe hacer cuando algo así sucede new ImplementingClass().abstractMethod()
.
Aquí hay una correcta ImplementingClass
.
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
}
Tenga en cuenta que no tiene que definir implementedMethod()
o finalMethod()
. Ya estaban definidos por AbstractClass
.
Aquí hay otro correcto ImplementingClass
.
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
public void implementedMethod() { System.out.print("Overridden!"); }
}
En este caso, lo ha anulado implementedMethod()
.
Sin embargo, debido a la final
palabra clave, 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()
in AbstractClass
está marcada como la implementación final de finalMethod()
: no se permitirán otras implementaciones, nunca.
Ahora se puede también aplicar una clase abstracta en dos ocasiones:
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 AbstractClass
tipo, se muestra "Overriden!"
. Esto se debe a que el objeto que instanciamos era en realidad un ImplementingClass
, que implementedMethod()
por supuesto se anula. (Es posible que haya visto esto denominado polimorfismo).
Si deseamos acceder a un miembro específico de una subclase particular, primero debemos bajar 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 se puede extender una clase a la vez. Si necesita extender varias clases, deben 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 compilador 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 debería 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. Como 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 compilador sabe que tiene que usar su método.
c.implementedMethod()
imprimiría "Overriden!" SecondImplementingClass
no anula implementedMethod()
.
Una clase 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 compilador lo 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 compilador lo obliga a marcar toda la clase como abstracta. 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 como lo hace una interfaz. Pero a diferencia de una interfaz, ya puede proporcionar funcionalidad, es decir, algunas partes de la clase se implementan y algunas partes solo se describen con una declaración de método. ("resumen")
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.
abstract
palabra clave es todo lo que se necesita para que una clase sea abstracta. Pero una clase concreta no puede contener un abstract
método . Por lo tanto, si su clase tiene un abstract
método, debe declararse como una abstract
clase para el compilador.
Una clase que se declara usando 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 al usuario. La abstracción te permite concentrarte en lo que hace el objeto en lugar de cómo lo hace.
Cosas principales 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:
ex: 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 instanciar (no está permitido crear objetos de la clase abstracta)
Para usar una clase abstracta, debes heredarla de otra clase. Proporcione implementaciones a todos los métodos abstractos que contiene.
Si hereda una clase abstracta, debe proporcionar implementaciones a todos los métodos abstractos que contiene.
Declarar clase abstracta La
especificación de una abstract
palabra clave antes de la clase durante la declaración la hace abstracta. Echa un vistazo al siguiente código:
abstract class AbstractDemo{ }
Declarar método abstracto
Especificar la abstract
palabra clave antes del método durante la declaración lo hace abstracto. Echa un vistazo al siguiente código,
abstract void moveTo();//no body
¿Por qué necesitamos abstraer clases?
En una aplicación de dibujo orientada a objetos, puede dibujar círculos, rectángulos, 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, rotar, 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 moveTo). Otros requieren una implementación diferente (por ejemplo: cambiar el tamaño o dibujar). Todos los objetos gráficos deben poder dibujar o cambiar su tamaño, solo 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 padre abstracto (por GraphicObject
ejemplo:) como se muestra en la siguiente figura.
Primero, declara una clase abstracta GraphicObject
, para proporcionar variables miembro y métodos que son totalmente compartidos por todas las subclases, como la posición actual y el método moveTo. GraphicObject
también declararon métodos abstractos, como dibujar o cambiar el tamaño, que deben implementarse en todas las subclases, pero deben implementarse de diferentes maneras. La GraphicObject
clase puede verse 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 subclase no abstracta de GraphicObject
, como Circle
y Rectangle
, debe proporcionar implementaciones para los métodos 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 main
método puede 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 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
Recuerda dos reglas:
Si la clase tiene pocos métodos abstractos y pocos métodos concretos, declararla como una abstract
clase.
Si la clase solo tiene métodos abstractos, declare como un interface
.
Referencias
Es una clase que no se puede instanciar, y obliga a implementar clases para, posiblemente, implementar métodos abstractos que describe.
Simplemente hablando, puedes pensar en una clase abstracta como una interfaz con un poco más de capacidades.
No se puede crear una instancia de una interfaz, que también es válida para una clase abstracta.
En su interfaz, puede definir los encabezados de los métodos 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í, a 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 implementar y, por lo tanto, también puede tener una sola clase abstracta por clase secundaria) su clase abstracta, no están obligados a implementar todos sus métodos de su clase abstracta, a menos que especifique 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();
}
De la documentación de Oracle
Métodos abstractos y clases:
Una clase abstracta es una clase que se declara abstracta; puede incluir o no métodos abstractos.
Las clases abstractas no se pueden instanciar, 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 una clase abstracta se subclasifica, la subclase generalmente proporciona implementaciones para todos los métodos abstractos en su clase padre. Sin embargo, si no es así, entonces la subclase también debe declararse abstracta .
Dado abstract classes
y interfaces
están relacionados, echa un vistazo a continuación 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 hizo recientemente. Piensa en una nueva pregunta para construir reputación ...
Editar:
Acabo de darme cuenta de que los carteles de esta y las preguntas a las que se hace referencia tienen el mismo nombre o al menos un nombre similar, pero el ID de usuario siempre es diferente. Entonces, o bien, hay un problema técnico, que Keyur tiene problemas para iniciar sesión nuevamente y encontrar las respuestas a sus preguntas o este es un tipo de juego para entretener a la comunidad SO;)
Poca adición a todas estas publicaciones.
A veces es posible que desee declarar una clase y, sin embargo, no saber cómo definir todos los métodos que pertenecen a esa clase. Por ejemplo, es posible que desee declarar una clase llamada Writer e incluir en ella un método miembro llamado write () . Sin embargo, no sabe cómo codificar write () porque es diferente para cada tipo de dispositivo Writer. Por supuesto, planea manejar esto derivando una subclase de Writer, como Impresora, Disco, Red y Consola.
Una clase abstracta no puede ser instanciada directamente, sino que debe derivarse para ser utilizable. 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 prevenir la instantación directa, p. Ej.
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 utilizar 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 las 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
}
}
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();
}
Una clase abstracta es una clase que se declara abstracta; puede incluir o no métodos abstractos. Las clases abstractas no pueden instanciarse, pero pueden subclasificarse.
En otras palabras, una clase que se declara con una 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, se pueden usar para crear referencias de objetos, porque el enfoque de Java para el polimorfismo 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 función en el ejemplo a continuación.
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();
}
}
Una clase abstracta es aquella que no está completamente implementada, pero proporciona una especie de plano para las subclases. Puede implementarse parcialmente porque contiene métodos concretos completamente definidos, pero también puede contener métodos abstractos. Estos son métodos con 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 pueden ser instanciadas, deben ser extendidas por al menos una subclase para ser utilizadas. Piense en la clase abstracta como la clase genérica, y las subclases están ahí para completar la información que falta.
No hace nada, solo proporciona una plantilla común que se compartirá para su subclase