The inheritance mini app

We have looked at the way we can create hierarchies of classes to model the system that fits our app. So, let's try out some simple code that uses inheritance. The completed code is in the Chapter 9 folder of the code download. It is called Inheritance Example.

Create three new classes in the usual way. Name one AlienShip, another Fighter, and the last one Bomber.

The following is the code for the AlienShip class. It is very similar to our previous class demo, AlienShip. The differences are that the constructor now takes an int parameter, which it uses to set the shield strength.

The constructor also outputs a message to the console, so we can see when it is being used. Additionally, the AlienShip class has a new method, fireWeapon, that is declared abstract. This guarantees that any class that subclasses AlienShip must implement its own version of fireWeapon. Notice the class has the abstract keyword as part of its declaration. We have to do this because one of its methods also uses the keyword abstract. We will explain the abstract method when discussing this demo and the abstract class when we talk about polymorphism. Create a class called AlienShip and type this code:

public abstract class AlienShip {
  private static int numShips;
  private int shieldStrength;
  public String shipName;

  public AlienShip(int shieldStrength){
    Log.i("Location: ", "AlienShip constructor");
    numShips++;
    setShieldStrength(shieldStrength);
  }

  public abstract void fireWeapon();
  // Ahh my body where is it?

  public static int getNumShips(){
    return numShips;
  }

  private void setShieldStrength(int shieldStrength){
    this.shieldStrength = shieldStrength;
  }

  public int getShieldStrength(){
    return this.shieldStrength;
  }

  public void hitDetected(){
    shieldStrength -=25;
    Log.i("Incoming: ", "Bam!!");
    if (shieldStrength == 0){
      destroyShip();
    }

  }

  private void destroyShip(){
    numShips--;
    Log.i("Explosion: ", "" + this.shipName + " destroyed");
  }

}

Now, we will implement the Bomber class. Notice the call to super(100). This calls the constructor of the super class with the value for shieldStrength. We could do further specific Bomber initialization in this constructor, but for now, we just print out the location so we can see when the Bomber constructor is being executed. Because we must, we also implement a Bomber specific version of the abstract fireWeapon method. Create a class called Bomber and type this code:

public class Bomber extends AlienShip {

  public Bomber(){
    super(100);
    // Weak shields for a bomber
    Log.i("Location: ", "Bomber constructor");
  }

  public void fireWeapon(){
    Log.i("Firing weapon: ", "bombs away");
  }
}

Now, we will implement the Fighter class. Notice the call to super(400). This calls the constructor of the super class with the value for shieldStrength. We could do further specific Fighter initialization in this constructor, but for now, we just print out the location so we can see when the Fighter constructor is being executed. Because we must, we also implement Fighter specific version of the abstract fireWeapon method. Create a class called Fighter and type this code:

public class Fighter extends AlienShip{

  public Fighter(){
    super(400);
    // Strong shields for a fighter
    Log.i("Location: ", "Fighter constructor");
  }

  public void fireWeapon(){
    Log.i("Firing weapon: ", "lasers firing");
  }

}

And here is our code in the onCreate method of MainActivity. As usual, enter this code after the call to setContentView. This is the code that uses our three new classes. The code looks quite ordinary and is nothing new; it is the output that is interesting:

Fighter aFighter = new Fighter();
Bomber aBomber = new Bomber();

// Can't do this AlienShip is abstract -
// Literally speaking as well as in code
// AlienShip alienShip = new AlienShip(500);

// But our objects of the subclasses can still do
// everything the AlienShip is meant to do

aBomber.shipName = "Newell Bomber";
aFighter.shipName = "Meier Fighter";

// And because of the overridden constructor
// That still calls the super constructor
// They have unique properties
Log.i("aFighter Shield:", ""+ aFighter.getShieldStrength());
Log.i("aBomber Shield:", ""+ aBomber.getShieldStrength());

// As well as certain things in certain ways
// That are unique to the subclass
aBomber.fireWeapon();
aFighter.fireWeapon();

// Take down those alien ships
// Focus on the bomber it has a weaker shield
aBomber.hitDetected();
aBomber.hitDetected();
aBomber.hitDetected();
aBomber.hitDetected();

Run the app and you will get the following output in the logcat window:

Location:﹕ AlienShip constructor
Location:﹕ Fighter constructor
Location:﹕ AlienShip constructor
Location:﹕ Bomber constructor
aFighter Shield:﹕ 400
aBomber Shield:﹕ 100
Firing weapon:﹕ bombs away
Firing weapon:﹕ lasers firing
Incomiming:﹕ Bam!!
Incomiming:﹕ Bam!!
Incomiming:﹕ Bam!!
Incomiming:﹕ Bam!!
Explosion:﹕ Newell Bomber destroyed

We can see how the constructor of the subclass can call the constructor of the super class. We can also clearly see that the individual implementations of the fireWeapon method work exactly as expected.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.129.67.26