java - tener - para que sirve una clase abstracta
¿Puede una clase abstracta tener un constructor? (21)
Aunque hay muchas respuestas buenas, me gustaría dar mis 2 centavos.
El constructor NO CONSTRUYE EL OBJETO . Se utiliza para inicializar un objeto.
Sí, una clase abstracta siempre tiene un constructor. Si no define su propio constructor, el compilador le dará un constructor predeterminado a la clase Abstract. Lo anterior es válido para todas las clases: anidadas, abstractas, anónimas, etc.
Una clase abstracta (a diferencia de la interfaz) puede tener campos no estáticos no finales que necesitan inicialización. Puedes escribir tu propio constructor en la clase abstracta para hacer eso. Pero, en ese caso, no habrá ningún constructor por defecto.
public abstract class Abs{
int i;
int j;
public Abs(int i,int j){
this.i = i;
this.j = j;
System.out.println(i+" "+j);
}
}
Tenga cuidado al extender por encima de la clase abstracta, tiene que llamar explícitamente a super desde cada constructor. La primera línea de cualquier constructor llama a super (). Si no llama explícitamente a super (), Java lo hará por usted. A continuación el código no se compilará:
public class Imp extends Abs{
public Imp(int i, int j,int k, int l){
System.out.println("2 arg");
}
}
Tienes que usarlo como ejemplo de abajo:
public class Imp extends Abs{
public Imp(int i, int j,int k, int l){
super(i,j);
System.out.println("2 arg");
}
}
¿Puede una clase abstracta tener un constructor?
Si es así, ¿cómo puede usarse y con qué fines?
Como lo describe javafuns here , este es un ejemplo:
public abstract class TestEngine
{
private String engineId;
private String engineName;
public TestEngine(String engineId , String engineName)
{
this.engineId = engineId;
this.engineName = engineName;
}
//public gettors and settors
public abstract void scheduleTest();
}
public class JavaTestEngine extends TestEngine
{
private String typeName;
public JavaTestEngine(String engineId , String engineName , String typeName)
{
super(engineId , engineName);
this.typeName = typeName;
}
public void scheduleTest()
{
//do Stuff
}
}
Como una clase abstracta puede tener variables de todos los modificadores de acceso, deben inicializarse a valores predeterminados, por lo que el constructor es necesario. A medida que crea una instancia de la clase secundaria, se invoca un constructor de una clase abstracta y se inicializan las variables.
Por el contrario, una interfaz solo contiene variables constantes significa que ya están inicializadas. Así que la interfaz no necesita un constructor.
Considera esto:
abstract class Product {
int value;
public Product( int val ) {
value= val;
}
abstract public int multiply();
}
class TimesTwo extends Product {
public int mutiply() {
return value * 2;
}
}
La superclase es abstracta y tiene un constructor.
Definiría un constructor en una clase abstracta si se encuentra en una de estas situaciones:
- desea realizar alguna inicialización (en los campos de la clase abstracta) antes de que tenga lugar la instanciación de una subclase
- ha definido los campos finales en la clase abstracta pero no los inicializó en la declaración en sí; en este caso, DEBE tener un constructor para inicializar estos campos
Tenga en cuenta que:
- puede definir más de un constructor (con diferentes argumentos)
- puede (debería?) definir a todos sus constructores protegidos (hacerlos públicos no tiene sentido de todos modos)
- su (s) constructor (es) de subclase puede llamar a un constructor de la clase abstracta; incluso puede tener que llamarlo (si no hay un constructor sin argumentos en la clase abstracta)
En cualquier caso, no olvide que si no define un constructor, entonces el compilador generará automáticamente uno para usted (este es público, no tiene argumentos y no hace nada).
El propósito del constructor en una clase se usa para inicializar los campos pero no para "construir objetos". Cuando intenta crear una nueva instancia de una SuperClass abstracta, el compilador le dará un error. Sin embargo, podemos heredar una clase abstracta Empleado y hacer uso de su constructor configurando sus variables Vea el ejemplo a continuación
public abstract class Employee {
private String EmpName;
abstract double calcSalary();
Employee(String name) {
this.EmpName = name;// constructor of abstract class super class
}
}
class Manager extends Employee{
Manager(String name) {
super(name);// setting the name in the constructor of sub class
}
double calcSalary() {
return 0;
}
}
En una clase concreta, la declaración de un constructor para un tipo concreto Fnord expone efectivamente dos cosas:
Un medio por el cual el código puede solicitar la creación de una instancia de Fnord
Un medio por el cual una instancia de un tipo derivado de Fnord que está en construcción puede solicitar que se inicialicen todas las características de clase base.
Si bien debería haber un medio por el cual estas dos habilidades podrían controlarse por separado, para cada tipo concreto, una definición habilitará ambas. Aunque la primera habilidad no es significativa para una clase abstracta, la segunda habilidad es tan significativa para una clase abstracta como lo sería para cualquier otra, y por lo tanto su declaración es tan necesaria y útil.
La clase abstracta puede tener un constructor, aunque no puede ser instanciada. Pero el constructor definido en una clase abstracta se puede usar para la instanciación de la clase concreta de esta clase abstracta. Compruebe JLS :
Es un error en tiempo de compilación si se intenta crear una instancia de una clase abstracta utilizando una expresión de creación de instancia de clase .
Se puede crear una instancia de una subclase de una clase abstracta que no sea abstracta, lo que da como resultado la ejecución de un constructor para la clase abstracta y, por lo tanto, la ejecución de los inicializadores de campo para las variables de instancia de esa clase.
No solo puede hacerlo, siempre lo hace. Si no especifica uno, tiene un constructor no arg predeterminado, como cualquier otra clase. De hecho, TODAS las clases, incluidas las clases anidadas y anónimas, obtendrán un constructor predeterminado si no se especifica una (en el caso de clases anónimas es imposible especificar una, por lo que siempre obtendrá el constructor predeterminado).
Un buen ejemplo de una clase abstracta que tiene un constructor es la clase Calendar . Obtienes un objeto de Calendario llamando a Calendar.getInstance (), pero también tiene constructores que están protegidos. La razón por la que sus constructores están protegidos es para que solo sus subclases puedan llamarlos (o clases en el mismo paquete, pero como es abstracto, eso no se aplica). GregorianCalendar es un ejemplo de una clase que extiende el calendario.
Para lograr el encadenamiento de constructores, la clase abstracta tendrá un constructor. El compilador mantiene la instrucción Super () dentro del constructor de la subclase, que llamará al constructor de la superclase. Si no hubiera constructores para las clases abstractas, se violan las reglas de Java y no podemos lograr el encadenamiento de constructores.
Por supuesto, la clase abstracta puede tener un constructor. Generalmente, el constructor de la clase se usa para inicializar los campos. Por lo tanto, un constructor de la clase abstracta se usa para inicializar los campos de la clase abstracta. Debería proporcionar un constructor para una clase abstracta si desea inicializar ciertos campos de la clase abstracta antes de que se realice la creación de instancias de una clase secundaria. Un constructor de clases abstractas también se puede usar para ejecutar código relevante para cada clase secundaria. Esto evita la duplicación de código.
No podemos crear una instancia de una clase abstracta, pero podemos crear instancias de clases derivadas de la clase abstracta. Por lo tanto, cuando se crea una instancia de clase derivada, se llama automáticamente al constructor de la clase abstracta principal.
Referencia: Este artículo
Sí ... es como cualquier otra clase. Puede tener un constructor y se llama después de crear un objeto para la clase base.
Sí, los constructores de clases abstractas se usan generalmente para superclamadas para eventos de inicialización comunes a todas las subclases
Sí, puede tener un constructor y está definido y se comporta como cualquier otro constructor de clase. Excepto que las clases abstractas no pueden ser instanciadas directamente, solo extendidas, por lo que el uso siempre es del constructor de una subclase.
Sí, seguramente puede agregar uno, como ya se mencionó para la inicialización de las variables de clase Abstract. PERO si no declara explícitamente uno, de todos modos tiene un constructor implícito para que funcione el "Encadenamiento de constructores".
Sí, una clase abstracta puede tener un constructor. Considera esto:
abstract class Product {
int multiplyBy;
public Product( int multiplyBy ) {
this.multiplyBy = multiplyBy;
}
public int mutiply(int val) {
return multiplyBy * val;
}
}
class TimesTwo extends Product {
public TimesTwo() {
super(2);
}
}
class TimesWhat extends Product {
public TimesWhat(int what) {
super(what);
}
}
El Product
superclase es abstracto y tiene un constructor. La clase concreta TimesTwo
tiene un constructor que solo codifica el valor 2. La clase concreta TimesWhat
tiene un constructor que permite al llamante especificar el valor.
Los constructores abstractos se usarán con frecuencia para imponer restricciones de clase o invariantes como los campos mínimos requeridos para configurar la clase.
NOTA: Como no hay un constructor predeterminado (o no-arg) en la clase abstracta principal, el constructor utilizado en la subclase debe llamar explícitamente al constructor principal.
Sí, una clase abstracta puede tener un constructor. Puede sobrecargar tantos constructores como desee en una clase abstracta. Estos contratistas pueden utilizarse para inicializar el estado inicial de los objetos que extienden la clase abstracta. Como sabemos, no podemos hacer un objeto de una clase abstracta porque los objetos son creados por las palabras clave "nuevas" y no por los constructores ... están ahí solo para inicializar el estado de los objetos de la subclase.
Una clase abstracta puede tener un constructor PERO no puede crear un objeto de clase abstracta, entonces, ¿cómo usa ese constructor?
La cosa es que cuando hereda esa clase abstracta en su subclase puede pasar valores a su constructor (abstracto) a través del método super (value) en su subclase y no, no se hereda un constructor.
por lo tanto, al usar super puede pasar valores en un constructor de la clase abstracta y, por lo que recuerdo, debe ser la primera declaración en su método o constructor.
sí lo es. Y se llama a un constructor de clase abstracta cuando se crea una instancia de una clase heredada. Por ejemplo, el siguiente es un programa Java válido.
// An abstract class with constructor
abstract class Base {
Base() { System.out.println("Base Constructor Called"); }
abstract void fun();
}
class Derived extends Base {
Derived() { System.out.println("Derived Constructor Called"); }
void fun() { System.out.println("Derived fun() called"); }
}
class Main {
public static void main(String args[]) {
Derived d = new Derived();
}
}
Esta es la salida del código anterior,
Constructor base llamado Constructor derivado llamado
referencias: ingrese la descripción del enlace aquí
Sí, las clases abstractas pueden tener constructores!
Aquí hay un ejemplo usando constructor en clase abstracta:
abstract class Figure {
double dim1;
double dim2;
Figure(double a, double b) {
dim1 = a;
dim2 = b;
}
// area is now an abstract method
abstract double area();
}
class Rectangle extends Figure {
Rectangle(double a, double b) {
super(a, b);
}
// override area for rectangle
double area() {
System.out.println("Inside Area for Rectangle.");
return dim1 * dim2;
}
}
class Triangle extends Figure {
Triangle(double a, double b) {
super(a, b);
}
// override area for right triangle
double area() {
System.out.println("Inside Area for Triangle.");
return dim1 * dim2 / 2;
}
}
class AbstractAreas {
public static void main(String args[]) {
// Figure f = new Figure(10, 10); // illegal now
Rectangle r = new Rectangle(9, 5);
Triangle t = new Triangle(10, 8);
Figure figref; // this is OK, no object is created
figref = r;
System.out.println("Area is " + figref.area());
figref = t;
System.out.println("Area is " + figref.area());
}
}
Así que creo que tienes la respuesta.
Si si Clases abstractas pueden tener constructores !
Sí, cuando definimos una clase como una clase abstracta, no se puede crear una instancia, pero eso no significa que una clase abstracta no pueda tener un constructor. Cada clase abstracta debe tener una subclase concreta que implementará los métodos abstractos de esa clase abstracta.
Cuando creamos un objeto de cualquier subclase, todos los constructores en el árbol de herencia correspondiente se invocan en el enfoque de arriba a abajo. El mismo caso se aplica a las clases abstractas. Aunque no podemos crear un objeto de una clase abstracta, cuando creamos un objeto de una clase que es concreta y subclase de la clase abstracta, el constructor de la clase abstracta se invoca automáticamente. Por lo tanto podemos tener un constructor en clases abstractas.
Nota: una clase no abstracta no puede tener métodos abstractos, pero una clase abstracta puede tener un método no abstracto. La razón es similar a la de los constructores, la diferencia es que, en lugar de ser invocada automáticamente, podemos llamar super (). Además, no hay nada como un constructor abstracto, ya que no tiene ningún sentido en absoluto.