Search code examples
javainheritancesubclasssuperclassinstanceof

Confusion on using instanceof along with other inherited data


I have already made a posting about this program once, but I am once again stuck on a new concept that I am learning (Also as a side note; I am a CS student so please DO NOT simply hand me a solution, for my University has strict code copying rules, thank you.). There are a couple of difficulties I am having with this concept, the main one being that I am having a hard time implementing it to my purposes, despite the textbook examples making perfect sense. So just a quick explanation of what I'm doing: I have an entity class that takes a Scanner from a driver. My other class then hands off the scanner to a superclass and its two subclasses then inherit that scanner. Each class has different data from the .txt the Scanner read through. Then those three classes send off their data to the entity to do final calculations. And that is where my problem lies, after all the data has been read. I have a method that displays a new output along with a few methods that add data from the super along with its derived classes.EDIT: I simply cannot figure out how to call the instance variable of my subclasses through the super so I can add and calculate the data.

Here are my four classes in the order; Driver, Entity, Super, Subs:

    public static final String INPUT_FILE = "baseballTeam.txt";

    public static void main(String[] args) {
        BaseballTeam team = new BaseballTeam();
        Scanner inFile = null;
        try {
            inFile = new Scanner(new File(INPUT_FILE));
            team.loadTeam(inFile);
            team.outputTeam();
        } catch (FileNotFoundException e) {
            System.out.println("File " + INPUT_FILE + " Not Found.");
            System.exit(1);

        }
    }

}



public class BaseballTeam {

    private String name;
    private Player[] roster = new Player[25];

    Player pitcher = new Pitcher();
    Player batter = new Batter();

    BaseballTeam() {
        name = "";
    }

    public String getName() {
        return name;
    }

    public void setName(String aName) {
        name = aName;
    }

    public void loadTeam(Scanner input) {
        name = input.nextLine();
        for (int i = 0; i < roster.length; i++) {
            if (i <= 9) {
                roster[i] = new Pitcher();
            }
            else if ((i > 9) && (i <= 19)) {
                roster[i] = new Batter();
            }
            else if (i > 19) {
                roster[i] = new Player();
            }
            roster[i].loadData(input);
            roster[i].generateDisplayString();
            //System.out.println(roster[i].generateDisplayString());  //used sout to test for correct data
        } 

    }

    public void outputTeam() {
        if ((pitcher instanceof Player) && (batter instanceof Player)) {           
               for (int i = 0; i < roster.length; i++) {
            System.out.println(roster[i].generateDisplayString());
        } 
    }

//How do I go about doing calculates?
    public int calculateTeamWins() {        
             if ((pitcher instanceof ) && (batter instanceof Batter)) {

        }


        return 0;
    }

    public int calculateTeamSaves() {
        if ((pitcher instanceof Pitcher) && (batter instanceof Batter)) {

        }
        return 0;
    }

    public double calculateTeamERA() {
        if ((pitcher instanceof Pitcher) && (batter instanceof Batter)) {

        }
        return 0;
    }

    public double calculateTeamWHIP() {
        if ((pitcher instanceof Pitcher) && (batter instanceof Batter)) {

        }
        return 0;
    }

    public double calculateTeamBattingAverage() {
        if ((pitcher instanceof Pitcher) && (batter instanceof Batter)) {

        }
        return 0;
    }

    public int calculateTeamHomeRuns() {
        if ((pitcher instanceof Pitcher) && (batter instanceof Batter)) {

        }
        return 0;
    }

    public int calculateTeamRBI() {
        if ((pitcher instanceof Pitcher) && (batter instanceof Batter)) {

        }
        return 0;
    }

    public int calculateStolenBases() {
        if ((pitcher instanceof Pitcher) && (batter instanceof Batter)) {

        }
        return 0;
    }
}



public class Player {

    protected String name;
    protected String position;

     Player(){        

        name = "";
        position = "";        
    }
    public String getName() {
        return name;
    }

    public void setName(String aName) {
        name = aName;
    }

    public String getPosition() {
        return position;
    }

    public void setPosition(String aPosition) {
        position = aPosition;
    }  

    public void loadData(Scanner input){
        do {

            name = input.nextLine();
        } while (name.equals(""));
         position = input.next();
         //System.out.println(generateDisplayString());
    }

    public String generateDisplayString(){

        return "Name: " + name + ", Position:" + position; 
    }
}


public class Pitcher extends Player {

    private int wins;
    private int saves;
    private int inningsPitched;
    private int earnedRuns;
    private int hits;
    private int walks;
    private double ERA;
    private double WHIP;

    Pitcher() {
        super();
        wins = 0;
        saves = 0;
        inningsPitched = 0;
        earnedRuns = 0;
        hits = 0;
        walks = 0;
    }

    public int getWins() {
        return wins;
    }

    public void setWins(int aWins) {
        wins = aWins;
    }

    public int getSaves() {
        return saves;
    }

    public void setSaves(int aSaves) {
        saves = aSaves;
    }

    public int getInningsPitched() {
        return inningsPitched;
    }

    public void setInningsPitched(int aInningsPitched) {
        inningsPitched = aInningsPitched;
    }

    public int getEarnedRuns() {
        return earnedRuns;
    }

    public void setEarnedRuns(int aEarnedRuns) {
        earnedRuns = aEarnedRuns;
    }

    public int getHits() {
        return hits;
    }

    public void setHits(int aHits) {
        hits = aHits;
    }

    public int getWalks() {
        return walks;
    }

    public void setWalks(int aWalks) {
        walks = aWalks;
    }

    @Override
    public void loadData(Scanner input) {
        super.loadData(input);
        wins = input.nextInt();
        saves = input.nextInt();
        inningsPitched = input.nextInt();
        earnedRuns = input.nextInt();
        hits = input.nextInt();
        walks = input.nextInt();

    }

    @Override
    public String generateDisplayString() {
        calculateERA();
        calculateWHIP();
        return String.format(super.generateDisplayString() + ", Wins:%1d, Saves:%1d,"
                + " ERA:%1.2f, WHIP:%1.3f ", wins, saves, ERA, WHIP);
    }

    public double calculateERA() {
        try {
            ERA = ((double)(earnedRuns * 9) / inningsPitched);
        } catch (ArithmeticException e) {
            ERA = 0;
        }
        return ERA;
    }

    public double calculateWHIP() {
        try {
            WHIP = ((double)(walks + hits) / inningsPitched);
        } catch (ArithmeticException e) {
            WHIP = 0;
        }
        return WHIP;
    }
}


public class Batter extends Player {

    private int atBats;
    private int hits;
    private int homeRuns;
    private int rbi;
    private int stolenBases;
    private double batAvg;

    Batter() {
        super();
        atBats = 0;
        hits = 0;
        homeRuns = 0;
        rbi = 0;
        stolenBases = 0;
    }

    public int getAtBats() {
        return atBats;
    }

    public void setAtBats(int aAtBats) {
        atBats = aAtBats;
    }

    public int getHits() {
        return hits;
    }

    public void setHits(int aHits) {
        hits = aHits;
    }

    public int getHomeRuns() {
        return homeRuns;
    }

    public void setHomeRuns(int aHomeRuns) {
        homeRuns = aHomeRuns;
    }

    public int getRbi() {
        return rbi;
    }

    public void setRbi(int aRbi) {
        rbi = aRbi;
    }

    public int getStolenBases() {
        return stolenBases;
    }

    public void setStolenBases(int aStolenBases) {
        stolenBases = aStolenBases;
    }

    @Override
    public void loadData(Scanner input) {
        super.loadData(input);
        atBats = input.nextInt();
        hits = input.nextInt();
        homeRuns = input.nextInt();
        rbi = input.nextInt();
        stolenBases = input.nextInt();      
    }

    @Override
    public String generateDisplayString() {
        calculateBattingAverage();
        return String.format(super.generateDisplayString() +
                ", Batting Average:%1.3f, Home Runs:%1d, RBI:%1d, Stolen Bases:%1d"
                , batAvg, homeRuns, rbi, stolenBases);
    }

    public double calculateBattingAverage() {
        try{
        batAvg = ((double)hits/atBats);
        } catch (ArithmeticException e){
            batAvg = 0;
        }
        return batAvg;
    }
}

Also, its probably easy to tell I'm still fairly new here, because I just ran all my classes together in with the code sample and I can't figure out to add the gaps, so feel free to edit if need be.


Solution

  • The typical usage of instanceof in the type of scenario you're describing would be

    if (foo instanceof FooSubclass) {
      FooSubclass fooSub = (FooSubclass) foo;
      //foo and fooSub now are references to the same object, and you can use fooSub to call methods on the subclass
    } else if (foo instanceof OtherSubclass) {
      OtherSubclass otherSub = (OtherSubclass) foo;
      //you can now use otherSub to call subclass-specific methods on foo
    }
    

    This is called "casting" or "explicitly casting" foo to FooSubclass.