Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Dúvida sobre Herança - Criação de classes em um jogo.

Pessoal, Estou criando um projeto de um jogo de luta. Dentro dele tenho as seguintes 11 classes (a seguinte sempre herdando da anterior):

Heroes(1) -> Ninja(2.1) -> Personagem1(2.1.1)/ Personagem2(2.1.2)
Heroes (1)-> Warrior(2.2) -> Personagem3(2.2.1)/ Personagem4(2.2.2)
Heroes (1)-> Tanker(2.3) -> Personagem5(2.3.1)/ Personagem6(2.3.2)
Jogo (11 - Main)
  • Ninjas possuem determinados bônus;
  • Warriows possuem determinados bônus;
  • Tankers possuem determinados bônus;
  • Cada personagem pertence a uma dessas 3 classes, mas cada um possui habilidades individuais, portanto, preciso de separar cada um em sua própria classe.

O problema é que não estou conseguindo dar continuidade no projeto quando chego na criação das classes de cada personagem. Estou com dificuldade em instanciar o construtor.

Erro:

Exception in thread "main" java.lang.Error: Unresolved compilation problems: 
    Implicit super constructor Ninja() is undefined. Must explicitly invoke another constructor
    Cannot instantiate the type Ninja

    at Personagem1.<init>(Personagem1.java:4)
    at Game.main(Game.java:6)

Segue parte do projeto que creio que seja suficiente para sanar a dúvida:

public class Game {

    public static void main(String[] args) {

        Heroes personagem1 = new Personagem1();
        personagem1.getInfo();

    }
}
import java.text.DecimalFormat;
import java.util.Random;

abstract class Heroes {

    // ATTRIBUTES
    protected String name;
    protected String type;

    protected int agility;
    protected int defense;
    protected int strength;

    protected double damage; //STR + AGI
    protected double hp; // STR + DEF
    protected double stamina; // DEF + AGI

    // CONSTRUCTOR
    protected Heroes() {
    }

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

    public void setType(String type) {
        this.type = type;
    }

    public void setAgility(int agility) {
        this.agility = agility;
    }

    public void setDefense(int defense) {
        this.defense = defense;
    }

    public void setStrength(int attack) {
        this.strength = attack;
    }

    public void setDamage(double d) {
        this.damage = d;
    }

    public void setHp(double d) {
        this.hp = d;
    }

    public void setStamina(double d) {
        this.stamina = d;
    }

    // GETTERS
    DecimalFormat df = new DecimalFormat("####0.00");

    public String getName() {
        return name;
    }

    public String getType() {
        return type;
    }

    public int getAgility() {
        return agility;
    }

    public int getDefense() {
        return defense;
    }

    public int getStrength() {
        return strength;
    }

    public String getDamage() {
        return df.format(damage);
    }

    public String getHp() {
        return df.format(hp);
    }

    public String getStamina() {
        return df.format(stamina);
    }

    // RANDOM
    Random gen = new Random();

    public void skills() {
        int agi = 8 + gen.nextInt(9);
        int def = 8 + gen.nextInt(9);
        int str = 36 - agi - def;

        this.agility += agi;
        this.defense += def;
        this.strength += str;
    }

    // INFO
    public void getInfo() {
        System.out.println(this.name.toUpperCase());
        System.out.println("Type: " + this.getType());
        System.out.println("Agility: " + this.getAgility());
        System.out.println("Defense: " + this.getDefense());
        System.out.println("Strength: " + this.getStrength());
//        System.out.println("SOMA: " + (this.agility + this.attack + this.defense));
        System.out.println("DAMAGE: " + this.getDamage());
        System.out.println("HP: " + this.getHp());
        System.out.println("STAMINA: " + this.getStamina() + "\n");
    }

}
abstract class Ninja extends Heroes {

    protected Ninja(String name){
        this.name = name;
        this.type = "Ninja";
        this.setAgility(5);
        this.skills();
        this.setDamage((this.getAgility() + this.getStrength()) * 0.5);
        this.setHp((this.getStrength() + this.getDefense()) * 0.5);
        this.setStamina((this.getAgility() + this.getDefense()) * 0.65);


    }
}
public class Personagem1 extends Ninja {

    public Personagem1(){
    Ninja n1 = new Ninja("Personagem1");

    //HABILIDADE 1

    //HABILIDADE 2

    //HABILIDADE 3
    }
}
2 respostas
solução!

Oi Lucas,

o que o erro está te dizendo é que, como Personagem1 é um Ninja e, na criação do Ninja é preciso passar uma String name, o construtor da classe Personagem1 precisa passar isso para sua superclasse.

A solução é simples e a explicação é mais complexa, então vou começar com a solução. Em vez de instanciar um novo Ninja, você precisa passar a string para a superclasse do Personagem1.

Solução

public Personagem1(){
    super("Personagem1");
    // outras habilidades
}

Explicação

Quando você diz que uma classe é filha de outra, isso significa que ela tem tudo o que a mãe (superclasse) tem e faz tudo o que a mãe faz.

Para que isso seja possível, quando você instancia um Personagem1, o que ele faz internamente, nessa ordem, é o seguinte:

Você escreve: new Personagem1();

O compilador, internamente, faz: Verifica que Personagem1 é um Ninja Verifica se tem alguma chamada do super. Se não tem: Roda o construtor padrão, sem argumentos, do Ninja; Ele não existe, então dá pau de compilação. Se tem: Verifica se a superclasse Ninja tem o construtor chamado explicitamente; Se tem, compila.

Em tempo...

Eu entendi que a sua intenção com a linha Ninja n1 = new Ninja("Personagem1"); dentro do construtor de Personagem1 foi uma tentativa de fazer isso funcionar, mas não rola porque, dessa forma, você está criando uma nova instância de Ninja (composição, não herança), em vez de alterar o próprio objeto do Personagem1 que você tentou criar.

Não rola trabalhar dessa forma com herança. A relação, no caso de Personagem1 instanciar um objeto é a que um Personagem1 tem um Ninja, mas não que ele é um como quando usamos o extends.

[]s

Obrigado pela explicação, Cecilia!