example - Constructores por defecto en Java
table swing java (6)
Sé que estoy haciendo una pregunta seria 101 aquí ...
Tengo un Foo
clase y un Bar
clase que amplía Foo
. En Foo
tengo un constructor que toma un conjunto de parámetros que establece en sus campos. Las clases derivadas, como Bar
, normalmente no necesitarán modificar esto. Ahora mi IDE me está dando "No hay ningún constructor predeterminado disponible en Foo" . A partir de un poco de Google, esto parece ser porque "los constructores no son heredados". Así que todo bien y bien, pero ¿cómo puedo hacer que esto funcione sin duplicar este constructor en cada clase derivada? Supongo que hay un enfoque más sensato.
Así que todo bien y bien, pero ¿cómo puedo hacer que esto funcione sin duplicar este constructor en cada clase derivada?
Debe duplicar las firmas de los constructores, si desea que la subclase tenga constructores con las mismas firmas. Pero no necesita duplicar el código ; simplemente encadena al constructor de la superclase:
public Bar(int x, int y) {
super(x, y);
// Any subclass-specific code
}
Por supuesto, si puede resolver los parámetros de la superclase desde un conjunto diferente de parámetros, está bien. Por ejemplo:
public Bar(int x) {
super(x, x * 2);
// Any subclass-specific code
}
Realmente necesita averiguar qué información se necesita para construir un Bar
: eso debería dictar sus constructores.
Si esto es un problema, es posible que esté usando en exceso la herencia. Es difícil decirlo con certeza sin tener idea de cuáles son tus clases reales , pero debes considerar el uso de la composición en lugar de la herencia. No es una panacea, pero puede evitar este tipo de cosas.
El problema se resuelve con esto:
class Foo{
Foo(int a, int b){}
}
class Bar extends Foo{
//Here must be a constructor OR declare a constructor in Foo without parameters
Bar(){super(1,1)} //this is an example
}
Otra solución es:
class Foo{
Foo(int a, int b){}
Foo(){}
}
class Bar extends Foo{
}
Recuerda que si tienes un constructor con parámetros en la SuperClass (en este caso Foo), el constructor implícito en la clase child (en este caso Bar), siempre tendrá una llamada implícita a " Super () " (siempre tiene que ser uno) a menos que sea explícito).
JVM no proporcionará un constructor predeterminado si ha proporcionado uno por motivos de diseño. Lo que puedes hacer es definir el constructor en Bar con la misma firma y llamar a super ().
public Bar(int x,int y) {
super(x,y);
}
No, no hay más enfoque "sensato". Si su clase base no tiene un constructor predeterminado, debe llamar explícitamente al constructor correcto de todas las clases secundarias.
Tenga en cuenta que esto no significa que las clases para niños necesiten tener el mismo constructor exacto que la clase base. Por ejemplo, esto es perfectamente válido:
class Foo {
protected int a;
protected int b;
protected Foo(final int a, final int b) {
this.a = a;
this.b = b;
}
}
class Bar extends Foo {
protected Bar() {
super(0,0);
}
}
Si los parámetros no son necesarios y / o tienen valores predeterminados, puede definir el constructor predeterminado (sin parámetros):
class Foo
{
public final int DEFAULT_A = 42;
protected int a;
protected int b;
public Foo(final int a, final int b)
{
this.a = a;
this.b = b;
}
/* Is equal to new Foo(Foo.DEFAULT_A, 0); */
pubic Foo()
{
this.a = this.DEFAULT_A;
}
}
class Bar extends Foo {}
class PiBar extends Bar
{
public final int DEFAULT_A = Math.PI;
}
Usa el super
constructor:
public Bar(int a, double b, ...) {
super(a, b, ...);
}