Basic classes mini-app

The hypothetical real-time strategy (RTS) game we are writing will need more than one Soldier object. In our game that we are about to build we will instantiate and use multiple objects. We will also demonstrate using the dot operator on variables and methods to show that different objects have their own instance variables contained in their own memory slot.

You can get the completed code for this example in the download bundle. It is in the chapter 8/Basic Classes folder. Or read on to create your own working example from scratch.

Create a new project and call the application BasicClasses. Choose the Empty Activity template. Call the Activity RTSActivity. As usual, we don't need the Generate Layout File or Backwards Compatibility options. It doesn't really matter too much as we won't be returning to this project after this short exercise.

Creating your first class

After creating the new project we create a new class called Soldier. Select File | New | Java Class. You will see the following dialog box.

Creating your first class

Name the class as Soldier as I have done in the previous image and click OK.

The new class is created for us with a code template ready to put our implementation within. Just like the next image shows.

Creating your first class

Also, notice that Android Studio has put the class in the same package as the rest of our app. And now we can write its implementation.

Write the class implementation code below within the opening and closing curly braces of the Soldier class as shown. The new code is highlighted.

public class Soldier {
    int health;
    String soldierType;

    void shootEnemy(){
        //let's print which type of soldier is shooting
        Log.d(soldierType, " is shooting");
    }
}

You will have one error and the Log… code will be red. We need to import the Log class. Select the error with the mouse pointer and hold the ALT key and tap Enter to import the class.

Now we have a class, a blueprint for our future objects of type Soldier, we can start to build our army. In the editor window left-click the tab of RTSActivity.java. We will write this code, as so often, within the onCreate method just after the call to super.onCreate. Type this code.

// first we make an object of type soldier
Soldier rambo = new Soldier();
rambo.soldierType = "Green Beret";
rambo.health = 150;
// It takes allot to kill Rambo

// Now we make another Soldier object
Soldier vassily = new Soldier();
vassily.soldierType = "Sniper";
vassily.health = 50;
// Snipers have less health

// And one more Soldier object
Soldier wellington = new Soldier();
wellington.soldierType = "Sailor";
wellington.health = 100;
// He's tough but no green beret

Tip

If you aren't doing so already, this is a really good time to start taking advantage of the auto-complete feature in Android Studio. Notice after you have declared and created a new object, all you must do is begin typing the object's name and all the auto-complete options present themselves. The next image shows that when you type the letters we Android Studio suggests you might mean wellington. You can then just click, or press Enter to select wellington.

Creating your first class

Now we have our extremely varied and somewhat unlikely RTS army, we can use it and also verify the identity of each object. Type this code below the code in the previous step.

Log.i("Rambo's health = ", "" + rambo.health);
Log.i("Vassily's health = ", "" + vassily.health);
Log.i("Wellington's health = ", "" + wellington.health);

rambo.shootEnemy();
vassily.shootEnemy();
wellington.shootEnemy();

Tip

You will need to import the Log class into RTSActivity just as you did previously for Soldier.

Now we can run our game. All the output will be in the logcat window.

This is how it works. First, we created a template for our new Soldier class. Then we implemented our class including declaring two fields (member variables), an int and a String called health and soldierType respectively.

We also have a method in our class called shootEnemy. Let's look at it again and examine what is going on.

void shootEnemy(){
        // Let's print which type of soldier is shooting
        Log.d(soldierType, " is shooting");
}

In the body of the method, we print to the logcat. First, the String soldierType and then the arbitrary " is shooting". What is neat here is that the String soldierType will be different depending upon which object we call the shootEnemy method on. This demonstrates that each of the objects of type Soldier is different and stored in their own memory slot.

Next, we declared and created three new objects of type Soldier. They were rambo, vassily, and wellington. Finally, we initialized each with a different value for health as well as soldierType.

Here is the output:

Rambo's health =﹕ 150
Vassily›s health =﹕ 50
Wellington›s health =﹕ 100
Green Beret﹕ is shooting
Sniper﹕ is shooting
Sailor﹕ is shooting

Notice that each time we access the health variable of each Soldier object, it prints the value we assigned it, demonstrating that although the three objects are of the same type, they are separate, individual instances/objects.

Perhaps more interesting is the three calls to shootEnemy. One by one, each of our Soldier object's shootEnemy methods is called and we print the soldierType variable to the console. The method has the appropriate value for each individual object. Further demonstrating that we have three distinct objects (instances of the class), albeit created from the same Soldier class.

We saw how each object is completely independent of the other objects. However, if we imagine whole armies of Soldier objects in our app then we realize that we are going to need to learn new ways of handling large numbers of objects (and regular variables too).

Think about managing just 100 separate Soldier objects. What about when we have thousands of objects? In addition, this is not very dynamic. The way we are writing the code now relies on us (the game developers) knowing the exact details of the soldiers that the player will be commanding. We will see the solution for this in Chapter 12, Handling Lots of Data with Arrays.

More things we can do with our first class

We can treat classes/objects much like we can other types/variables. For example, we can use a class as a parameter in a method signature.

public void healSoldier(Soldier soldierToBeHealed){…

And when we call the method we must, of course, pass an object of that type. Here is a hypothetical call to the healSoldier method.

// Perhaps healSoldier could add to the health instance variable
healSoldier(rambo);

Of course, the above example might raise questions like, should the healSoldier method be a method of a class?

fieldhospital.healSoldier(rambo);

It could be or not. It would depend upon what is the best solution for the situation. We will look at more OOP and then the best solution for lots of similar conundrums should present themselves more easily.

And, as you might guess we can also use an object as the return value of a method. Here is what the updated hypothetical healSoldier signature and implementation might look like now.

Soldier healSoldier(Soldier soldierToBeHealed){
   soldierToBeHealed.health++;

   return soldierToBeHealed;
}

In fact, we have already seen classes being used as parameters. For example, in the SubHunter class, in the onCreate method, we instantiated an object of type Point called point and passed it as an argument to the getSize method using the display object. Here is the code again for easy reference.

Point size = new Point();
display.getSize(size);

All this information will likely raise a few questions. OOP is like that. Let's try and consolidate all this class stuff with what we already know by taking another look at variables and encapsulation.

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

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