StarWars.java Questions

Instructions

  1. With the left mouse button pressed, drag the mouse across the contents of the program listing that is shown below. This will select the program listing. Then choose Copy from the Edit menu of your web browser to copy the program listing to the clipboard.
  2. Start your text editor and create a new file called StarWars.java. Choose Paste to paste the contents of the program listing from the clipboard into the new file.
  3. Save the file to disk and begin answering the questions that are shown below.
  4. When you need to look at the model answer, click here.
  5. Click here to go back to the tutorials menu.

Program listing

// INHERITANCE TUTORIAL
// Copyright (C) 1998-2016 Davin Pearson
// Website: http://davin.50webs.com/java-tutorials

class XWing
{
   // Properties of the class...
   private int     shields;
   private int     weapon;
   private boolean dead;

   // Constructor of the class...
   public XWing()
   {
      shields = 1000;
      weapon  = 10;
   }

   // Methods of the class...
   public int getWeapon()
   {
      return weapon;
   }
   public boolean isDead()
   {
      return dead;
   }
   public void hit(int damage)
   {
      shields = shields - damage;
      if (shields < 0)
      {
         System.out.println("Boom!!!");
         dead = true;
      }
   }
}

class TieFighter {

   // Properties of the class...
   private int shields;
   private int weapon;
   private boolean dead;
  
   // Constructor of the class...
   public TieFighter()
   {
      shields = 500;
      weapon  = 20;
   }
   
   // Methods of the class...
   public int getWeapon()
   {
      return weapon;
   }
   public boolean isDead()
   {
      return dead;
   }
   public void hit(int damage)
   {
      shields = shields - damage;
      if (shields < 0)
      {
         System.out.println("Boom!!!");
         dead = true;
      }
   }
}

class StarWars {

   private void duel(XWing x, TieFighter t)
   {
      for (;;)
      {
         x.hit(t.getWeapon());       
         if (x.isDead())
         {
            System.out.println("X-Wing is dead");
            break;
         }
         t.hit(x.getWeapon());
         if (t.isDead())
         {
            System.out.println("Tie Fighter is dead");
            break;
         }
      }

   }

   private void battle(XWing[] good, TieFighter[] evil)
   {
      int g = 0;
      int e = 0;
      int goodDeaths = 0;
      int evilDeaths = 0;
      while (g < good.length && e < evil.length)
      {
         System.out.println("battling X-Wing #" + g +
                            " versus Tie Fighter #" + e);
         duel(good[g],evil[e]);
         if (good[g].isDead())
         {
            g++;
            goodDeaths++;
         }
         if (evil[e].isDead())
         {
            e++;
            evilDeaths++;
         }
      }

      int finalGood = good.length - goodDeaths;
      int finalEvil = evil.length - evilDeaths;

      System.out.println();
      System.out.println("Battle Report:\t\tX-Wings\t\tTie Fighters");
      System.out.println("------------------------------------------------------");
      System.out.println();
      System.out.println("Initial ships:\t\t" + good.length + "\t\t" + evil.length);
      System.out.println();
      System.out.println("Killed ships:\t\t"  + goodDeaths  + "\t\t" + evilDeaths);
      System.out.println();
      System.out.println("Final ships:\t\t"   + finalGood   + "\t\t" + finalEvil);
      System.out.println();
      if (finalGood > finalEvil)
      {
         System.out.println("The rebel alliance is victorious!");
      }
      else
      {
         System.out.println("The dark side has conquered!");
      }
      System.out.println();
   }

   public void doStuff()
   {
      // defines the goodies array
      XWing[] goodies = new XWing[3];

      // initialises the elements of the goodies array
      for (int i=0; i<goodies.length; i++)
      {
         goodies[i] = new XWing();
      }
    
      // defines the baddies array
      TieFighter[] baddies = new TieFighter[3];

      // initialises the elements of the baddies array
      for (int i=0; i<baddies.length; i++)
      {
         baddies[i] = new TieFighter();
      }
    
      battle(goodies,baddies);
   }  

   // The main method is the point of entry into the program...
   public static void main(String[] args)
   {
      StarWars me = new StarWars();
      me.doStuff();
   }
}


// QUESTIONS:
//
// (1) Compile and run this file to see the battle between the
// X-Wings and the Tie Fighters unfold.
//
// (2) If you look at the Java code for the XWing and
// TieFighter classes you will notice that they are almost
// identical: They have the same methods and properties, the
// only difference is that the XWing objects are initialised
// with a different value for their shields and weapon
// properties to the TieFighter objects.

// The next few questions will guide you through the process
// of using inheritance to eliminate this unnecessary
// duplication of code.  A new class called "SpaceShip" will
// be created and all of the code that is common to XWing
// and TieFighter will be moved into this class.  The XWing
// and TieFighter classes will then be modified so that they
// both inherit from SpaceShip.

// (3) The first step in this process is to create the outer
// shell of the SpaceShip class, which you should now
// type in:

//  class SpaceShip {
//  }

// (4) Move the properties "shields", "weapon" and "dead"
// out of the XWing and TieFighter classes and into the
// SpaceShip class.  You must change the privacy status of
// the properties from private to protected.

// The protected modifier was invented as an intermediate
// level of privacy between public and private.  Like
// private, it allows visibility to the same class in which
// the method or property was defined, but unlike private it
// also allows visibility to subclasses of the class in
// which the method or property was defined.

// (5) Move the three methods getWeapon, isDead and hit out
// of the XWing and TieFighter classses and into the
// SpaceShip class.  At this point, the XWing and TieFighter
// classes should contain nothing but a constructor.
// 
// (6) Finally, add the extends keyword to the first line of
// the XWing and TieFighter classes:

//  class XWing extends SpaceShip {
//  ...
//  class TieFighter extends SpaceShip {
// 
// (7) Compile and run your program again, making sure
// that it produces the same results now that it is using
// inheritance.

// (8) The SpaceShip class is a superclass of both XWing and
// TieFighter containing everything that X-Wings and Tie
// Fighters contain in common.  Because the role of the
// SpaceShip class is simply to hold these commonalities, we
// might choose to label the class with the abstract
// keyword:

//  abstract class SpaceShip {

// This prevents us from creating instances of the SpaceShip
// class.  Without the abstract modifier, we could happily
// create a new SpaceShip(), which would be an object that
// is not an X-Wing, nor a Tie Fighter, but just a vague
// "space ship".  If we consider this to be a logical
// mistake then we can use abstract to prevent such calls to
// the SpaceShip constructor.

// Change the class SpaceShip to be abstract and observe how
// the compiler will not accept any lines of the form:

//  SpaceShip s = new SpaceShip();

// Remove the abstract keyword and notice how the compiler
// will then allow this line to compile.