Make all the things…classes

Make all the things…classes

This is a continuation on my series of articles on object-oriented programming. The first article, discusses how you can use role-playing game characters as a metaphor for object classes, and the second, discusses how party-systems and roles introduce polymorphism and class hierarchy.

Now that we have a basic character class and our character sheets, we can start to learn how these can be created in Java as object-oriented classes.


Classes in Java define four main things:

  1. What is the name of the class and how does it fit within the hierarchy and how is it classified using an interface
  2. What are the values that are stored and used within each unique instance of the class
  3. What are the actions that each unique instance of the class can perform
  4. What rules govern how each unique instance is created during construction

Creating some class

We can start with the first, naming the class. In Java we do that using the class statement. Each unique class is stored as a specific file, generally with the same name as the class.

If we look at our mage character sheet, this gives us a good reference to use as we create the class.

In our IDE, we will need to create our project and then create a file for the class. This file would be called Mage.java.

When we create the file, we then need to populate the class name and then use the class statement. A code block, using braces, then surrounds the code that defines the blueprint for our class. You'll notice that the only unique thing about a constructor method is that you don't need to provide a return type:

public class Mage {
}

We start with the public statement, since we want the class to be available within the program to use and create instances—we will cover more about the public statement in a bit. Then we follow with the class statement, and then the name of the class. Classes are usually capitalized, and each word is capitalized with no spaces.

Now that we have defined the basics of the class, we can start adding properties, or fields as they are sometimes called, to the class. These are essentially variables that will be unique for each instance of the class. Just like any other variable in Java, we need to type them to a primitive or class type and then give them a valid variable name.

We define these at the top of our class, within the class code block. If we look at our character sheet, we have nine items we need to add to our Mage class. These include the name of the character, the skill attributes and the expendable assets for health and magic, remembering that health and magic each are two individual values, the maximum possible value and the current value for the instance.

To define these, we need to declare their access level, which in this case would be public. If you have worked previously with basic Java apps without classes, you might have had to use public static. For this class, we only need to use public:

public class Mage {
   // Name
   public String name;
 
   // Skill attributes
   public int strength;
   public int intelligence;
   public int agility;
   public int wisdom;
 
   // Health and magic
   public int maxHitPoints;
   public int hitPoints;
   public int maxMana;
   public int mana;
}

Now, for each instance of our class, we will have nine unique fields that we can use and store values. These are unique and exclusive to each instance, but each instance will have all nine of these fields.

Now, we need to tell our class how to build each instance, or construct each instance. We do that with a special method called the constructor. The constructor method is the same name as the class, and has a code block to contain all of the rules for how we construct each instance, just like a regular method.

The constructor is usually placed after the fields have been defined at the top of the class:

public class Mage {
   // Name
   public String name;
 
   // Skill attributes
   public int strength;
   public int intelligence;
   public int agility;
   public int wisdom;
 
   // Health and magic
   public int maxHitPoints;
   public int hitPoints;
   public int maxMana;
   public int mana;
 
   Mage() {
       // Constructor
   }
}

Inside the constructor we can then create the specific rules for how we create each class instance. For example, the skill attributes are calculated based on a specific number and the value of a 6-sided die. The hit points and mana are calculated based on the values of the skill attributes:

public class Mage {
   // Name
   public String name;
 
   // Skill attributes
   public int strength;
   public int intelligence;
   public int agility;
   public int wisdom;
 
   // Health and magic
   public int maxHitPoints;
   public int hitPoints;
   public int maxMana;
   public int mana;
 
   Mage() {
       // Constructor
       strength = 7;
       intelligence = 15;
       agility = 8;
 
       wisdom = 10;
 
       strength += (int) (Math.random() * 6 + 1);
       intelligence += (int) (Math.random() * 6 + 1);
       agility += (int) (Math.random() * 6 + 1);
       wisdom += (int) (Math.random() * 6 + 1);
 
       maxHitPoints = hitPoints = strength;
       maxMana = mana = intelligence + (wisdom * 2);
   }
}

The last item we need to populate is the name. The name is something that we need to get more information on in order to create it. To do that, we can require that each time you create a mage, you need to provide a name, then that name is saved in the name field for the class instance. We can pass in a value into the constructor just like any Java method:

public class Mage {
   // Name
   public String name;
 
   // Skill attributes
   public int strength;
   public int intelligence;
   public int agility;
   public int wisdom;
 
   // Health and magic
   public int maxHitPoints;
   public int hitPoints;
   public int maxMana;
   public int mana;
 
   Mage(String newName) {
       // Constructor
       name = newName;
       
       strength = 7;
       intelligence = 15;
       agility = 8;
 
       wisdom = 10;
 
       strength += (int) (Math.random() * 6 + 1);
       intelligence += (int) (Math.random() * 6 + 1);
       agility += (int) (Math.random() * 6 + 1);
       wisdom += (int) (Math.random() * 6 + 1);
 
       maxHitPoints = hitPoints = strength;
       maxMana = mana = intelligence + (wisdom * 2);
   }
}

Finally, we need our mage to be able to do something. We can create a method that will display the stats of our mage, so we can see the attributes and health information for our instance. We would create that as a regular method, providing a return type (which in this case is void) and then wrap everything in a code block. We can then refer to the values, or fields, in our class by their variable names:

public class Mage {
   // Name
   public String name;
 
   // Skill attributes
   public int strength;
   public int intelligence;
   public int agility;
   public int wisdom;
 
   // Health and magic
   public int maxHitPoints;
   public int hitPoints;
   public int maxMana;
   public int mana;
 
   Mage(String newName) {
       // Constructor
       name = newName;
 
       strength = 7;
       intelligence = 15;
       agility = 8;
 
       wisdom = 10;
 
       strength += (int) (Math.random() * 6 + 1);
       intelligence += (int) (Math.random() * 6 + 1);
       agility += (int) (Math.random() * 6 + 1);
       wisdom += (int) (Math.random() * 6 + 1);
 
       maxHitPoints = hitPoints = strength;
       maxMana = mana = intelligence + (wisdom * 2);
   }
 
   public void showStats() {
       System.out.println("----------------------------------");
       System.out.println(name + ", a mage:");
       System.out.println("   Strength: " + strength);
       System.out.println("Intelligence: " + intelligence);
       System.out.println("    Agility: " + agility);
       System.out.println("     Wisdom: " + wisdom);
       System.out.println(" Hit Points: " + hitPoints + " / " + maxHitPoints);
       System.out.println("       Mana: " + mana + " / " + maxMana);
       System.out.println();
   }
}

We now have a complete class. We have defined the class name, identified the fields in the class, specified the rules that govern how each class instance is created, and have given the class an action to perform.

Instantiate thyself, Class!

To create an instance of our class, we need to then go back to where our main() method is in our program. In the past, we have always used the main() method to start our program, and generally in Java, the main() method is the consistent starting point for every program.

In another class file, in this case, I called mine Main.java, I have a standard main() method that will start the program:

public class Main {
   public static void main(String[] args) {
   }
}

In my method, I can then create an instance of our new Mage class. Just like with any variable or container, I would need to define the type of value that is going to be stored in the variable. In this case, we would type it to the class. So the type—is Mage. We then need to provide a name for the class instance, which I will call myMage. We then say that we are creating a new instance of the Mage class with the new statement, and then trigger construction by calling the constructor method. Our constructor requires a String to be passed in with the character's name:

public class Main {
   public static void main(String[] args) {
       Mage myMage = new Mage("Francisco");
   }
}

We now have our first instance of the Mage class created! But it we run the program, nothing happens. To prove that we have an instance created, we can add a line to the constructor that outputs text to the screen when an instance is built. We can add this line to the end of our constructor:

public class Mage {
   // Name
   public String name;
 
   // Skill attributes
   public int strength;
   public int intelligence;
   public int agility;
   public int wisdom;
 
   // Health and magic
   public int maxHitPoints;
   public int hitPoints;
   public int maxMana;
   public int mana;
 
   Mage(String newName) {
       // Constructor
       name = newName;
 
       strength = 7;
       intelligence = 15;
       agility = 8;
 
       wisdom = 10;
 
       strength += (int) (Math.random() * 6 + 1);
       intelligence += (int) (Math.random() * 6 + 1);
       agility += (int) (Math.random() * 6 + 1);
       wisdom += (int) (Math.random() * 6 + 1);
 
       maxHitPoints = hitPoints = strength;
       maxMana = mana = intelligence + (wisdom * 2);
 
       System.out.println("A new mage named " + name + " has been created!");
   }
 
   public void showStats() {
       System.out.println("----------------------------------");
       System.out.println(name + ", a mage:");
       System.out.println("   Strength: " + strength);
       System.out.println("Intelligence: " + intelligence);
       System.out.println("    Agility: " + agility);
       System.out.println("     Wisdom: " + wisdom);
       System.out.println(" Hit Points: " + hitPoints + " / " + maxHitPoints);
       System.out.println("       Mana: " + mana + " / " + maxMana);
       System.out.println();
   }
}

Now if we run our program, we get this message in the output panel:

A new mage named Francisco has been created!
 
Process finished with exit code 0

We can then access and work with various fields in our program, and execute actions that the instance can perform:

public class Main {
   public static void main(String[] args) {
       Mage myMage = new Mage("Francisco");
       
       System.out.println(myMage.agility);
       
       myMage.showStats();
   }
}

We use the name of the class instance, myMage, to refer to the unique instance of the Mage class and then access the fields and methods of that instance to run our program.

A new mage named Francisco has been created!
14
----------------------------------
Francisco, a mage:
   Strength: 10
Intelligence: 19
    Agility: 14
     Wisdom: 15
 Hit Points: 10 / 10
       Mana: 49 / 49
 
 
Process finished with exit code 0

Since we have a class, we can then create multiple instances of that class, referring to each one using a unique name:

public class Main {
   public static void main(String[] args) {
       Mage myMage = new Mage("Francisco");
       myMage.showStats();
       
       Mage myOtherMage = new Mage("Jaana");
       myOtherMage.showStats();
   }
}

Our two instances share identical blueprints, fields, methods and constructors, but the values stored within it are unique and exclusive to that instance. So when we run this program, we see the different values in each instance displayed on the screen:

A new mage named Francisco has been created!
----------------------------------
Francisco, a mage:
   Strength: 12
Intelligence: 19
    Agility: 13
     Wisdom: 16
 Hit Points: 12 / 12
       Mana: 51 / 51
 
A new mage named Jaana has been created!
----------------------------------
Jaana, a mage:
   Strength: 13
Intelligence: 18
    Agility: 12
     Wisdom: 16
 Hit Points: 13 / 13
       Mana: 50 / 50
 
 
Process finished with exit code 0

With this basic class structure, we can then expand and build on it. For our game, we have four unique player character types. We have a mage, fighter, priest and paladin. Each of these would be a unique class, and we can create a unique class file and definition for each one, and then create as many instances of them as we want.

Additional information

For more information on how to create classes in Java, check out this video from my "Computer Science Principles Lab: Java" course on LinkedIn Learning:

#roleplaying #games #learntocode #java #programming #programmer

要查看或添加评论,请登录

Rich Winnie的更多文章

  • Attacking a Stroke at 45.

    Attacking a Stroke at 45.

    Hi everyone! This announcement may come as a surprise for everyone, but I wanted to take the time to relate some news…

    119 条评论
  • Putting It All Together

    Putting It All Together

    Putting It All Together What I have attempted to present here are the guideposts that I have seen throughout my career…

    4 条评论
  • Your Release Learning Channel

    Your Release Learning Channel

    Finally, there is the release channel. You have taken this skill to your everyday activities or have changed your…

    1 条评论
  • Your Beta Learning Channel

    Your Beta Learning Channel

    We’ve heard the feedback. We have taken it to heart.

    3 条评论
  • Your Dev Learning Channel

    Your Dev Learning Channel

    We all want people to build us up. We want promoters, advocates, and supporters to be hungry for new things and to have…

    3 条评论
  • Your Canary Learning Channel

    Your Canary Learning Channel

    You’ve validated and tested new skills with yourself and you are ready to start sharing them with other people. You…

  • What’s Win It For Me: Let’s See What We’ve Learned—Windows 11

    What’s Win It For Me: Let’s See What We’ve Learned—Windows 11

    Greetings readers! Digital Mindset is expanding! We will now have two threads of articles coming to you. This issue…

  • Your Selfhost Learning Channel

    Your Selfhost Learning Channel

    When you are a software developer, you are always building new things. You are creating completely new features for…

    1 条评论
  • Your Learning Channels

    Your Learning Channels

    If you use Windows, you might be familiar with the Windows Insider Program. The Insider Program is a community based on…

    1 条评论
  • The Value Curve Cycle

    The Value Curve Cycle

    Along the course of the phases and steps, we have discussed the learning journey as a singular “thing.” We must…

    3 条评论

社区洞察