Das klingt vielleicht etwas komisch, aber lassen Sie mich das erklären. Ich habe eine Superklasse, die mehrere Parameter erfordert. Ein solcher Parameter ist ein BufferedImage Objekt. Um dieses BufferedImage in der untergeordneten Klasse als Parameter zu initialisieren, muss ich natürlich try and catch-Blöcke verwenden. Das kann ich nur mit einer Methode der untergeordneten Klasse, die im Konstruktor aufgerufen wird. Das Problem ist, dass der Konstruktor super() das erste im Konstruktor der untergeordneten Klasse sein muss. Daher kann ich die Methode zum Initialisieren von BufferedImage nicht aufrufen, bevor ich super() aufrufe. Wie kann ich mein BufferedImage Objekt korrekt initialisieren, bevor ich es als Parameter verwende, wenn ich super() in meinem untergeordneten Klassenkonstruktor aufrufe?

Beispiel: Super- / Elternklasse

public class CombatEntity {
    BufferedImage sprite; 
    public CombatEntity(String name, BufferedImage sprite) {
        //do something
    }
}

Beispiel: Kinderklasse

public class Batman {
     BufferedImage sprite;
     Batman() {
         super("Bruce Wayne", sprite); //sprite hasn't been properly initalized

     }

     void getSprite() { //I need to call this method before super in order to initalize my image
          try {
              File f = new File("Batman.png");
              sprite = ImageIO.read(f);
          }

          catch(Exception e) {
              //whatever
          }

     }

}
0
Ashwin Gupta 23 Dez. 2015 im 00:10

3 Antworten

Beste Antwort

Mach so etwas:

Erstellen Sie in der übergeordneten Klasse einen normalen Konstruktor, der Name- und Sprite-Parameter verwendet. Generieren Sie die Getter- und Setter-Methode gemäß der JavaBeans-Spezifikation.

CombatEntity:

   public class CombatEntity {

    protected String name;

    protected BufferedImage sprite; 

    public CombatEntity(String name, BufferedImage sprite) {
        this.name = name;
        this.sprite = sprite;
    }

    /*
     * Getters and Setters 
     */

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public BufferedImage getSprite() {
        return sprite;
    }

    public void setSprite(BufferedImage sprite) {
        this.sprite = sprite;
    }   
}

Erstellen Sie in der Batman-Klasse (untergeordnete Klasse) zwei Konstruktoren - einen ohne Parameter, mit denen Sie ein Batman-Objekt erstellen können, bevor Sie das Sprite-Image initialisieren, und einen zweiten, der dem übergeordneten Konstruktor ähnelt. Wenn Sie einen Konstruktor ohne Parameter aufrufen, ruft er den übergeordneten Konstruktor auf und setzt seine Parameter auf den Standardwert. Anschließend können Sie generateSpriteImage (String spriteImagePath) ausführen, um ein Sprite-Image aus dem injizierten Pfad zu erstellen.

Batman:

public class Batman extends CombatEntity{

    //Default constructor with no parameters 
    public Batman(){
        super("", null);
    }

    public Batman(String name, BufferedImage sprite){
        super(name, sprite);
    }

    public void generateSpriteImage(String spriteImagePath) {
        try {
            File file = new File(spriteImagePath);
            this.sprite = ImageIO.read(file);
        }

        catch(Exception e) {
            //whatever
        }
   }
}

Hoffe das wird dir helfen.

2
G.Spansky 22 Dez. 2015 im 21:43

Die einzige Möglichkeit, dies zu beheben, besteht darin, einen Image-Parameter in Ihrem Batman-Konstruktor anzufordern. Dieses Problem ist nicht ungewöhnlich und einer der Gründe, das Javabeans-Muster einzuhalten, bei dem jede Klasse einen Nullkonstruktor sowie Getter und Setter hat.

1
ControlAltDel 22 Dez. 2015 im 21:23

Ihr CombatEntity könnte eine abstract Methode getSprite() definieren und diese im Konstruktor aufrufen. Die untergeordnete Klasse (Batman) muss diese Methode implementieren.

Der Vorteil ist, dass Sie nach dem Erstellen des Objekts keine zusätzliche Methode aufrufen müssen (wie in der anderen Antwort vorgeschlagen).

1
Erik P 22 Dez. 2015 im 21:49