java - 对如何使用抽象类处理项目感到困惑

标签 java abstract-class

所以我正在做一个项目,我要创建不同“小动物”的二维模拟。这些小动物在 GUI 上相互交互,并会互相争斗。我的问题是我正在使用一个名为 Simulation 的类,该类用于模拟 2d 环境。在这门课中,我使用了诸如

之类的行
if (c.getSpecies() == Species.ANT)
//do something

这给了我一个错误,告诉我找不到符号 Species 或 ANT。我很确定这是因为 Simulation 没有从我的主要 *GVcritter** 类继承任何东西,而 Simulation 不应该有任何继承。话虽这么说,但我不太确定如何在不使用上述 if 语句的情况下执行此操作。

主要GVcritter类:

import java.awt.*; 
/***********************************************************
GVcritter represents a generic critter with several
characteristics: location, species, color and the number
of steps taken.  All other critters in the simulation
extend this class and add a few methods.

@author Scott Grissom
@version August 2016
 ***********************************************************/
public abstract class GVcritter {

    /** critter location */
    protected Location myLocation;

    /** critter color */
    private Color myColor;

    /** critter species */
    private Species mySpecies;

    /** number of steps taken during the simulation */
    protected int steps;

    /***********************************************************
    These enubmerated types are used throughout the simulation
    classes.
     ***********************************************************/ 
    public static enum Direction {
        NORTH, SOUTH, EAST, WEST, NONE
    };

    public static enum Attack {
        ROAR, POUNCE, SCRATCH, FORFEIT
    };

    public static enum Species {
        NONE, ANT, BIRD, HIPPO, VULTURE, TIGER
    };

    /***********************************************************
    These abstract methods MUST BE IMPLEMENTED by all classes
    that extend GVcritter.
     ***********************************************************/   
    public abstract Attack getAttack(GVcritter opponent);

    public abstract Direction getMoveDirection();

    /***********************************************************
    Instantiate and initialize the instance variables.

    @param l location of the critter
     ***********************************************************/     
    public GVcritter(Location loc){
        myLocation = loc;
        myColor = Color.WHITE;
        mySpecies = Species.NONE;
        steps = 0;
    }

    /***********************************************************
    Returns the critter species
    @returns the species
     ***********************************************************/      
    public final Species getSpecies(){
        return mySpecies;
    }

    /***********************************************************
    Sets the critter species
    @param s the species
     ***********************************************************/      
    public final void setSpecies(Species s){
        mySpecies = s;
    }   

    /***********************************************************
    Returns the critter color
    @returns the color
     ***********************************************************/      
    public final Color getColor(){
        return myColor;
    }

    /***********************************************************
    Sets the critter color
    @param c the color
     ***********************************************************/      
    public final void setColor(Color c){
        myColor = c;
    }   

    /***********************************************************
    Sets the critter location
    @param loc the location
     ***********************************************************/      
    public final void setLocation(Location loc){
        myLocation = loc;
    }

    /***********************************************************
    Returns the critter location
    @returns the location
     ***********************************************************/      
    public final Location getLocation(){
        return myLocation;
    }
}

模拟类:

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

/****************************************************
 * Simulates a 2D world of critters that move around
 * and fight if they inhabit the same location.
 * 
 * @author Scott Grissom 
 * @version August 2016
 ***************************************************/
public class Simulation extends GVcritter{
    Random gen = new Random();

    /** a 2D world of critters */
    private GVcritter[][] theWorld;

    /** a collection of all live critters */
    private ArrayList <GVcritter> allCritters;

    /** control size of the world */
    private final int ROWS=50, COLUMNS=70, SIZE=10;

    /** number of Ants alive in the simulation */
    private int numAnts;

    private int stepCount, numBirds, numHippos, numVultures, numTigers;

    /****************************************************
    Constructor instantiates and initializes all 
    instance members.
     ****************************************************/
    public Simulation(){
        theWorld = new GVcritter[ROWS][COLUMNS];
        allCritters = new ArrayList<GVcritter>();   
        numAnts=0;
        stepCount = 0;
        numAnts = 0;
        numBirds = 0;
        numHippos = 0;
        numVultures = 0;

        // set the appropriate size of the invisibile drawing area
        setPreferredSize(new Dimension(COLUMNS*SIZE, ROWS*SIZE));
    }

    /****************************************************
    Add the requested number of Ants into the simulation.
    Repeatedly ask for a random location that is free.
    Increment the number of Ants in the simulation.

    @param num number of ants
     ****************************************************/ 
    public void addAnts(int num){
        numAnts += num;
        for(int i=1;i<=num;i++){
            // create a new Ant at an open location
            Location loc = getOpenLocation();
            Ant c = new Ant(loc);
            placeCritter(c);
        }
    }

    public void addBirds(int num) {
        numBirds += num;
        for (int i=1; i<=num; i++)
        {
            Location loc = getOpenLocation();
            Bird c = new Bird(loc);
            placeCritter(c);
        }
    }

    public void addHippos(int num) {
        numHippos += num;
        for (int i=1; i<=num; i++)
        {
            Location loc = getOpenLocation();
            Hippo c = new Hippo(loc);
            placeCritter(c);
        }
    }

    public void addVultures(int num) {
        numVultures += num;
        for (int i=1; i<=num; i++)
        {
            Location loc = getOpenLocation();
            Vulture c = new Vulture(loc);
            placeCritter(c);
        }
    }

    public void addTigers(int num) {
        numTigers += num;
        for (int i=1; i<=num; i++)
        {
            Location loc = getOpenLocation();
            Tiger c = new Tiger(loc);
            placeCritter(c);
        }
    }

    /******************************************************
    Move forward on step of the simulation
     *****************************************************/  
    /* public void oneStep(){

    // shuffle the arraylist of critters for better performance
    Collections.shuffle(allCritters);
    stepCount++;

    // step throgh all critters using traditional for loop
    for(int i=0; i<allCritters.size(); i++){
    GVcritter attacker = allCritters.get(i);

    // what location does critter want to move to?
    GVcritter.Direction dir = attacker.getMoveDirection();
    Location previousLoc = attacker.getLocation();
    Location nextLoc = getRelativeLocation(previousLoc, dir);  

    // who is at the next location?
    GVcritter defender = theWorld[nextLoc.getRow()][nextLoc.getColumn()];

    // no critters here so OK for critter 1 to move
    if(defender == null){
    theWorld[nextLoc.getRow()][nextLoc.getColumn()] = attacker;
    attacker.setLocation(nextLoc);
    theWorld[previousLoc.getRow()][previousLoc.getColumn()] = null;

    // both critters the same species so peacefully bypass 
    }else if(attacker.getSpecies() == defender.getSpecies()){

    // update critter locations
    attacker.setLocation(nextLoc);
    defender.setLocation(previousLoc);

    // update positions in the world
    theWorld[nextLoc.getRow()][nextLoc.getColumn()] = attacker;
    theWorld[previousLoc.getRow()][previousLoc.getColumn()] = defender;

    //different species so they fight at location of critter 2
    }else if(attacker.getSpecies() != defender.getSpecies()){
    fight(attacker, defender);
    }
    }

    // update drawing of the world
    repaint();
    }*/

    /******************************************************
    Step through the 2D world and paint each location white
    (for no critter) or the critter's color.  The SIZE of 
    each location is constant.

    @param g graphics element used for display
     *****************************************************/      
    public void paintComponent(Graphics g){
        for(int row=0; row<ROWS; row++){
            for(int col=0; col<COLUMNS; col++){
                GVcritter c = theWorld[row][col];

                // set color to white if no critter here
                if(c == null){
                    g.setColor(Color.WHITE);
                    // set color to critter color   
                }else{    
                    g.setColor(c.getColor());
                }

                // paint the location
                g.fillRect(col*SIZE, row*SIZE, SIZE, SIZE);
            }
        }
    }

    public String getStats() {
        return "Steps: " + stepCount + "\nAnts: " + numAnts + "\nBirds: " + numBirds + "\nHippos: " + numHippos + "\nVultures: " + numVultures;
    }

    private Location getOpenLocation() {
        int randRow, randCol;
        boolean isEmpty = false;
        Location loc = new Location();

        do {
            randRow = gen.nextInt(50);
            randCol = gen.nextInt(70);

            if (theWorld[randRow][randCol] == null)
                isEmpty = true;
        } while (!isEmpty);

        loc.setRow(randRow);
        loc.setColumn(randCol);

        return loc;
    }

    private void placeCritter(GVcritter c) {
        Location critterLoc = c.getLocation();
        int row = critterLoc.getRow(), col = critterLoc.getColumn();

        allCritters.add(c);
        theWorld[row][col] = c;
    }

    private Location getRelativeLocation(Location loc, GVcritter.Direction d) {
        int row = loc.getRow(), col = loc.getColumn();
        Location neighbor = new Location();
        switch(d) {
            case NORTH:
            if (row == 0)
            {
                neighbor.setRow(ROWS);
                neighbor.setColumn(col);
            }
            else
            {
                neighbor.setRow(row - 1);
                neighbor.setColumn(col);
            }
            break;
            case EAST:
            if (col == COLUMNS)
            {
                neighbor.setRow(row);
                neighbor.setColumn(0);
            }
            else
            {
                neighbor.setRow(row);
                neighbor.setColumn(col + 1);
            }
            break;
            case SOUTH:
            if (row == ROWS)
            {
                neighbor.setRow(0);
                neighbor.setColumn(col);
            }
            else
            {
                neighbor.setRow(row - 1);
                neighbor.setColumn(col);
            }
            break;
            case WEST:
            if (col == 0)
            {
                neighbor.setRow(row);
                neighbor.setColumn(COLUMNS);
            }
            else
            {
                neighbor.setRow(row);
                neighbor.setColumn(col - 1);
            }
            break;
        }
        return neighbor;
    }

    public void reset() {
        for (int i=0; i<ROWS; i++)
            for (int j=0; i<COLUMNS; j++)
                theWorld[i][j] = null;
        allCritters.clear();
        numAnts = 0;
        stepCount = 0;
        numBirds = 0;
        numHippos = 0;
        numVultures = 0;
    }

    private void critterDies(GVcritter c) {
        int location;
        if (c.getSpecies() == Species.ANT) {
            numAnts--;
            location = 0;  
            for (GVcritter e: allCritters)
            {
                if (e.get(location) == c)
                    e.remove(location);
                location++;
            }
        }

        else if (c == Species.BIRD) {
            numBirds--;
            location = 0;  
            for (GVcritter e: allCritters)
            {
                if (e.get(location) == c)
                    e.remove(location);
                location++;
            }
        }

        else if (c == Species.HIPPO) {
            numHippos--;
            location = 0;  
            for (GVcritter e: allCritters)
            {
                if (e.get(location) == c)
                    e.remove(location);
                location++;
            }
        }

        else if (c == Species.VULTURE) {
            numVultures--;
            location = 0;  
            for (GVcritter e: allCritters)
            {
                if (e.get(location) == c)
                    e.remove(location);
                location++;
            }
        }

        else if (c == Species.TIGER) {
            numTigers--;
            location = 0;  
            for (GVcritter e: allCritters)
            {
                if (e.get(location) == c)
                    e.remove(location);
                location++;
            }
        }
    } 

    public void fight(GVcritter attacker, GVcritter defender) {
        Location attackLoc = attacker.getLocation();
        Location defendLoc = defender.getLocation();
        int attackRow = attackLoc.getRow(), attackCol = attackLoc.getColumn();
        int defendRow = defendLoc.getRow(), defendCol = defendLoc.getColumn();

        theWorld[attackRow][attackCol] = null;

        if (attackerWins(attacker, defender))
        {
            //critterDies(defender);
            theWorld[defendRow][defendCol] = attacker;
        }

        else
        {
            //critterDies(attacker);
        }
    }

    private boolean attackerWins(GVcritter attacker, GVcritter defender) {
        if (attacker.getAttack(defender) == Attack.POUNCE && defender.getAttack(attacker) == Attack.ROAR)
            return true;

        else if (attacker.getAttack(defender) == Attack.POUNCE && defender.getAttack(attacker) == Attack.SCRATCH)
            return false;

        else if (attacker.getAttack(defender) == Attack.SCRATCH && defender.getAttack(attacker) == Attack.ROAR)
            return false;

        else if (attacker.getAttack(defender) == Attack.SCRATCH && defender.getAttack(attacker) == Attack.POUNCE)
            return true;

        else if (attacker.getAttack(defender) == Attack.ROAR && defender.getAttack(attacker) == Attack.SCRATCH)
            return true;

        else if (attacker.getAttack(defender) == Attack.ROAR && defender.getAttack(attacker) == Attack.POUNCE)
            return false;

        else 
        {
            if (Math.random() < 0.5)
                return true;
            else
                return false;
        }
    }
}

我的问题出现在我的 critterDies()、fight() 和 attackerWins() 方法中。感谢您的帮助!

最佳答案

Species.ANT 不是顶级类。自从 它是GVcritter的一个内部类,改变 Species.ANTGVcritter.Species.ANT

关于java - 对如何使用抽象类处理项目感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41044766/

相关文章:

java - 在 JPA (EclipseLink) 中有一个类似 @Formula 的注释来设置来自子查询的计算字段?

java - Comparable vs Number,设计选择

java - 尽管 ListView 和 SimpleAdapter 有数据,Android ListView 不显示项目

java - 将 json 字符串转换为 java arraylist(使用 jackson)

java - 抽象、扩展和创建实例问题

java - 一个 ArrayList 中的多个对象类型

java - 我可以在抽象类中创建一个为实例化类构造实例的方法吗?

java - 我可以避免在子类中实现参数化构造函数吗

java - 通过单个连接将数千个客户端连接到 Jabber 服务器

java - 列表更改列表中的值