2013-11-01 7 views
0

Я столкнулся с проблемой дизайна в своем java-коде. В моем приложении используются ракеты, и есть разные типы ракет, которые работают одинаково, кроме трех уникальных атрибутов. Конструктор ракеты должен знать эти атрибуты. Я решил сделать ракеты абстрактным классом, но я не могу назначать значения защищенным переменным в подклассе вне метода/конструктора. Кроме того, я не могу объявить переменные в конструкторе, потому что сначала должен сделать вызов супер-конструктору. Как я могу быть умным в этой проблеме?Java как реализовать и разработать абстрактный класс

public abstract class Missile { 

private int x, y; 
private Image image; 
boolean visible; 

private final int BOARD_WIDTH = 390; 

protected final int MISSILE_SPEED; 
protected final int MISSILE_HEIGHT; 
protected String file; 

public Missile(int x, int y) { 
    ImageIcon ii = 
     new ImageIcon(this.getClass().getResource(file)); 
    image = ii.getImage(); 
    visible = true; 
    this.x = x; 
    this.y = y - Math.floor(MISSILE_HEIGHT/2); 
} 


public Image getImage() { 
    return image; 
} 

public int getX() { 
    return x; 
} 

public int getY() { 
    return y; 
} 

public boolean isVisible() { 
    return visible; 
} 

public void move() { 
    x += MISSILE_SPEED; 
    if (x > BOARD_WIDTH) 
     visible = false; 
} 
} 

И есть идеальная реализация подкласса, за исключением того, что он не работает. (он не может распознать защищенные переменные). Что я делаю?

public class Laser extends Missile { 

    MISSILE_SPEED = 2; 
    MISSILE_HEIGHT = 5; 
    file = "laser.jpg"; 

public Laser(int x, int y) { 
    super(x, y); 
} 

}

+0

@ trevor-e Нет, компилятор по-прежнему запрашивает у них идентификатор – user2651804

+0

, почему вы не задаете конструктор класса Missile, чтобы принять MISSILE_SPEED/MISSILE_HEIGHT. Они могут быть переданы из подклассов, но их не нужно открывать из конструкторов подкласса. –

+0

@DevBlanked. Поскольку у меня есть только две разные ракеты, это избавит вас от необходимости вообще абстрагироваться. Я просто не думаю, что это очень хорошее решение, чтобы дать параметры ракеты 4 int. Я искал способ избежать этого. – user2651804

ответ

3

Изменение базового класса полей и конструкторами в

И подкласса:

public class Laser extends Missile { 
    public Laser(int x, int y) { 
     super(x, y, 2, 5, "laser.jpg"); 
    } 

    ... 
} 

Атрибуты уже в базовом классе, поэтому они не должны быть переопределены в подклассе. Именование всех прописных букв зарезервировано для констант в Java.

+0

Это хорошее быстрое решение, если OP не планирует добавлять дополнительные поля позже на imo.В противном случае количество аргументов конструктора будет расти совсем немного, и вам нужно будет реорганизовать шаблон Builder для его управления. –

+0

Да или для переноса нескольких полей в объект (например, точка для x и y.Это гораздо лучше, чем вызывать переопределяемый метод из конструктора базового класса, например, принятый ответ. Это плохая практика, потому что поля подкласса еще не будут инициализированы, когда метод вызывается конструктором базового класса. –

3

Я думаю, что лучший способ сделать то, что вы хотите сделать, это абстрактные методы в Missile, что подклассы должны реализовывать. Например, добавить их к Missile:

public abstract int getMissileSpeed(); 
public abstract int getMissileHeight(); 
public abstract int getFileName(); 

Тогда ваш подкласс должен реализовать его, и вы можете сделать его постоянным, как так:

public class Laser extends Missile { 

    public Laser(int x, int y) { 
     super(x, y); 
    } 

    public int getMissileSpeed() { 
     return 2; 
    } 

    public int getMissileHeight() { 
     return 5; 
    } 

    public String getFileName() { 
     return "laser.jpg"; 
    } 

} 

редактировать: И тогда, конечно, в любом месте, что вы хотите получить постоянное значение, которое вы просто вызываете этими методами.

+0

Да, я экспериментировал с этой мыслью. Я надеялся, что это не придет. Любая причина, по которой у вас нет абстрактного метода для атрибута файла? (так как разные ракеты имеют разные анимации) – user2651804

+0

@ user2651804 Извините, что забыл добавить это! Мне действительно нравится это решение, потому что вы можете легко масштабировать столько свойств, сколько вам нужно. Для этого вы просто добавляете базовый абстрактный класс Missile, а затем ваша среда IDE должна помочь вам легко добавить их во все подклассы. –

1

Я не уверен, что если ракета должна быть абстрактным классом, но я думаю, что что-то подобное может быть то, что вы собираетесь:

public abstract class Missile { 

    private int x, y; 
    private Image image; 
    boolean visible; 

    private final int BOARD_WIDTH = 390; 

    protected final int MISSILE_SPEED; 
    protected final int MISSILE_HEIGHT; 

    public Missile(int x, int y, int speed, int height, String file) { 
     MISSILE_SPEED = speed; 
     MISSILE_HEIGHT = height; 

     ImageIcon ii = new ImageIcon(this.getClass().getResource(file)); 
     image = ii.getImage(); 
     visible = true; 
     this.x = x; 
     this.y = y - Math.floor(MISSILE_HEIGHT/2); 
    } 

} 

public class Laser extends Missile { 

    public Laser(int x, int y) { 
     super(x, y, 2, 5, "laser.jpg"); 
    } 

} 
0

Создать интерфейс и поместить все конечные поля Это. Теперь реализуйте этот интерфейс внутри Ракеты и Лазера. По крайней мере, это решило бы проблему доступа.

+1

Это может быть решение, которое мне может понравиться. Это просто не очень подробный ответ - можете ли вы уточнить, как это будет работать? – user2651804

Смежные вопросы