6.5. Konstruktører i underklasser

Vi minder om, at:

En underklasse skal selv definere, hvordan dets objekter skal kunne oprettes, så den skal selv definere sine konstruktører. Underklassen kan også have færre eller flere konstruktører end superklassen.

Når man definerer en konstruktør på en underklasse, skal man kun initialisere den nye del af objektet.

Har man f.eks. tilføjet nye variabler, skal konstruktøren initialisere dem. Den arvede del af objektet initialiseres ved, at man fra underklassens konstruktør kalder en konstruktør fra superklassen. Dette gøres med sætningen: "super(...);" med eventuelle parametre. Man bruger altså her super som en metode. Det skal gøres som den første sætning i konstruktøren. Hvis man ikke selv kalder super() som det første, sker der det, at super bliver kaldt automatisk uden parametre.

Figur 6-8. Boks3medDensitet tillader oprettelse på to måder

Herunder definerer vi Boks3medDensitet, der arver fra Boks3. Den nye egenskab er massefylden og metoden vægt(). Den skal kunne oprettes med: new Boks3medDensitet(), som opretter boksen med nogle standardværdier eller med: new Boks3medDensitet(lgd,b,h,d), hvor d er densiteten (massefylden).

public class Boks3medDensitet extends Boks3
{
  private double densitet;

  public Boks3medDensitet()
  {
    // super(); overflødig, den kaldes implicit
    densitet = 10.0;
  }

  public Boks3medDensitet(double lgd, double b,  
          double h, double densitet)
  {
    // kald superklassens konstruktør
    super(lgd,b,h);
    this.densitet = densitet;
  }

  public double vægt()
  {
    return volumen() * densitet;    // superklassen udregner volumen for os
  }
}

Konstruktører skal defineres på ny i en underklasse

En konstruktør i en underklasse kalder først en af superklassens konstruktører

Superklassens konstruktør kan kaldes med: super(parametre)

Hvis programmøren ikke kalder en af superklassens konstruktører, indsætter Java automatisk et kald af superklassens konstruktør uden parametre

Disse regler kombineret med reglerne for standardkonstruktøren har nogle pudsige konsekvenser. Lad os se på et eksempel med al overflødig kode skåret væk:

public class A
{
  public A(int i)
  {
  }
}

og

public class B extends A
{

}

Dette vil ikke oversætte, fordi B af Java vil blive lavet om til:

public class B extends A
{
  public B() // indsættes automatisk af Java
  {
    super();
  }
}

Standardkonstruktøren i B vil altså prøve at kalde konstruktøren i A uden parametre, men den findes jo ikke, fordi A har en anden konstruktør. Oversætteren kommer med fejlmeddelelsen "constructor A() not found".

Der er derimod ingen problemer med:

public class A
{
}

og

public class B extends A
{
}

Java laver det om til:

public class A
{
  public A() // indsættes automatisk af Java
  {
  }
}

og

public class B extends A
{
  public B() // indsættes automatisk af Java
  {
    super();
  }
}