2016-04-07 10 views
1

Dieser Titel drückt nicht, was ich meine ganz gut, ich entschuldige mich, aber es ist schwierig für mich besser auszudrücken, weil ich nicht ganz verstehen, was aufgrund der OOP mangel los ist Wissen und Erfahrung.Inherit Unterklasse Variable von super in Java

Ich baue ein grundlegendes Spiel, bei dem der Spieler mit einem "Helden" -Sprite um ein Brett herumlaufen und von einem "badGuy" -Sprite gejagt werden soll. Da die beiden Sprites 5-6 Methoden teilen, habe ich beschlossen, eine Superklasse "Sprite" und zwei Klassen "Hero erweitert Sprite" und "BadGuy erweitert Sprite" zu machen. Jetzt für alle jene Super Methoden, einschließlich Sachen wie:

getX(); getY(); getBounds(); render(); 

arbeiten ich die Super-Klasse müssen die Lage der ‚Hero‘ und ‚badguy‘ zu verfolgen. So implementiert I ‚Sprite‘ wie folgt aus:

package game.sprites; 

import javafx.scene.shape.Rectangle; 

import javax.swing.*; 
import java.awt.*; 

public class Sprite { 

    public static int x; 
    public static int y; 
    private int imageWidth; 
    private int imageHeight; 
    public Image image; 

    public Sprite(int x, int y) { 
     Sprite.x = x; 
     Sprite.y = y; 
    } 

    public static void render(Graphics g, Image image) { 
     g.drawImage(image, x, y, null); 
    } 

    public Image loadImage(String filePath) {...} 

    public void getImageDimensions() {...} 

    public Rectangle getBounds() { 
     return new Rectangle(x, y, imageWidth, imageHeight); 
    } 

    public Image getImage() { 
     return image; 
    } 

    public int getX() { 
     return x; 
    } 

    public int getY() { 
     return y; 
    } 
} 

Das Problem anspringt, wenn ich unterschiedliche Startkoordinaten zu ‚Hero‘ geben wollen und ‚BadGuy‘ Objekte. Wenn ich sie jetzt anders setze, überschreibt der zweite Aufruf von "Sprite" den ersten und beide beginnen an der gleichen Stelle (was sehr frustrierend wäre, wenn dein Ziel ist, von "badGuy" zu starten). ‚Hero‘ und ‚BadGuy‘ sind zur Zeit auf diese Weise initialisiert:

public class BadGuy extends Sprite { 

    public BadGuy() { 
     super(x, y); 
     initBadGuy(); 
    } 

    public void initBadGuy() { 
     loadImage("resources/craft.gif"); 
     getImageDimensions(); 
     x = 860; // Hero x = 20; 
     y = 560; // Hero y = 20; 
    } 

Also, was ich versucht zu tun ist, machen überschreiben die Subklassen Sprite der x und y. Aber ich habe es gegoogelt und ich verstehe, dass das eine sehr schlechte Idee ist und somit ist es nicht möglich. Also ist meine Frage etwas wie: Wie kann ich 'Sprite' dazu bringen, Unterklassen 'x' und 'y' Variablen zu erben und die notwendigen Methoden auszuführen, wenn die bestimmte Unterklasse aufgerufen wird.

Jetzt schaue ich es an - sowohl der Konstruktor und init <>() sind identisch für die Unterklassen, also vielleicht können sie stattdessen in "Sprite" implementiert werden? Nur ein Gedanke, aber ich bin schon ziemlich verwirrt, also keine Ahnung.

Danke.

+0

nur hinzufügen Konstruktor Held (int x, int y) und BadGuy (int x, int y), um Ihre Unterklassen Aufruf von Super (x, y). – BigMike

+3

Es ist, weil Sie die X- und Y-Variablen in Sprite STATIC gemacht haben. Dies bedeutet, dass jede Unterklasse, die die Variable ändert, bewirkt, dass diese Änderung in allen anderen angezeigt wird. Machen Sie sie einfach geschützt, und die Unterklassen werden dann in der Lage sein, – jr593

+0

zu bewältigen. Machen Sie die Variablen 'x' und' y' NICHT 'statisch'. Sie sollten Instanzvariablen der Klasse sein. Sie sollten jedes Sprite-Objekt verfolgen. Sie sollten auch in Erwägung ziehen, die 'Sprite'-Klasse' abstract' zu erstellen. –

Antwort

1

Sie erhalten dieses Problem, weil x und y als statische Felder in Ihrer Sprite Klasse deklariert sind.
Von JLS 8.3.1.1. static Fields

Wenn ein Feld statisch deklariert ist, gibt es genau eine Inkarnation des Feldes, unabhängig davon, wie viele Instanzen (möglicherweise null) der Klasse schließlich erstellt werden kann. Ein statisches Feld, manchmal auch als Klassenvariable bezeichnet, wird inkorporiert, wenn die Klasse initialisiert wird (§ 12.4).

Verwenden folgenden Code:

ändern Sprite-Klasse wie folgt:

public class Sprite { 

    public int x; 
    public int y; 
    .... 
} 

BadGuy Klasse:

public class BadGuy extends Sprite { 
    public BadGuy(int x, int y) { 
     super(x, y); 
     ... 
    } 
    .... 
} 

Heldenklasse:

public class Hero extends Sprite { 
    public Hero(int x, int y) { 
     super(x, y); 
     ... 
    } 
    .... 
} 

aus der Main-Klasse gehen Sie wie folgt: // Von wo Sie Object beider Klassen erstellen möchten

public static void main(String[] args){ 
Hero hero = new Hero(20,20); 
BadGuy badGuy= new BadGuy(860,560); 
} 
+0

Beachten Sie auch die Verwendung von 'static' im Kontext der Frage. –

+0

@SumitSingh danke, dass du dir Zeit genommen hast, um es im Detail zu erklären. Noch eine Sache (damit ich die Dinge besser verstehen kann): Kann ich die Startkoordinaten in den Unterklassen zuweisen, anstatt sie als Argumente an den Konstruktor jeder Unterklasse zu übergeben, wenn sie aufgerufen wird. Da sie in jedem Spiel an der gleichen Stelle beginnen, ist es sinnvoll, diese Startkoordinaten in der Klasse zu verkapseln. Oder zumindest macht es für mich Sinn: D – Alex