// Player 1's stats
int player1Health = 100;
int player1Gold = 50;
// Player 2's stats (getting messy...)
int player2Health = 100;
int player2Gold = 50;
// Whoops, which health am I changing?
player1Health = healPlayer(player2Health, 5); // Easy mistake!
Methods helped a bit, but we still pass variables around separately. Wouldnโt it be great if all these stats lived in one place?
Subsection3.4.1A Single โEntityโ That Owns Its Data
Letโs pretend we want to treat the player as a single entity, storing all of that playerโs stats in one โbox.โ We also want that โboxโ to have special โbuttonsโ (like โhealโ or โadd goldโ) that automatically change that playerโs stats.
This might look empty and useless, but weโve just done something powerful: weโve created a new type in Java. Just like int lets us create numbers and String lets us create text, Player will let us create... well, players! Weโll fill in what that means exactly, but the key idea is there: Java lets us create our own types to represent anything we need in our programs.
public class Player {
// These belong to the Player now
int health;
int gold;
}
This is like saying "every Player has their own health and gold." When we create a Player (using new Player()), Java sets aside space for both variables. Theyโll start at 0 by default, which isnโt greatโwe usually want to pick starting values like (10, 50). Weโll fix that next, but first appreciate what weโve done: weโve moved from separate, floating variables to a single container that keeps related data together.
Remember how our variables defaulted to 0? Thatโs not great for a gameโwe want to choose starting values. If this was a method, weโd write something like:
public static Player createPlayer(int startHealth, int startGold) {
// ... somehow make a Player with these values ...
}
Since creating objects with initial values is something we do constantly, Java gives us special syntax for itโa shorter, cleaner way to write this common task:
public class Player {
int health;
int gold;
// Like createPlayer, but special syntax!
// Constructor syntax:
// 1. Same name as the class
// 2. No return type (not even void)
// 3. public ClassName(parameters) { ... }
public Player(int startHealth, int startGold) {
health = startHealth; // set this Player's health
gold = startGold; // set this Player's gold
}
}
Now instead of calling createPlayer(10, 50), we write:
This special method is called a constructor. You might wonder: "Doesnโt it return a Player?" It does, but Javaโs grammar treats constructors speciallyโthey implicitly return the new object without needing a return type. Thatโs why:
Subsection3.4.5Step 4: Adding "Operations" for That Player
Remember how we wrote methods before? Each had a return type (like int or void) and parameters in parentheses. Weโll do the same here, but inside our class:
Java secretly translates this to something like โcall heal with the data belonging to player1.โ Thatโs what this means in an instance methodโitโs a reference to "the object weโre calling this method on." So:
public class Player {
int health;
int gold;
// ...constructor as before...
public Player(int startHealth, int startGold) {
health = startHealth;
gold = startGold;
}
// The method is right next to the data it changes
public void heal(int amount) {
health += amount; // directly use this Player's health
}
public void addGold(int amount) {
gold += amount; // same for gold
}
}
// Create an object using the Player class:
Player p = new Player(10, 50);
p.heal(5); // can't mix up which health we're changing!
Subsubsection3.4.5.1The โthisโ Keyword: Who Am I?
When writing instance methods, you might wonder: "How does Java know which Playerโs health to change?" The answer is the this keyword.
public class Player {
int health;
// ...other fields...
public void heal(int health) { // Uh oh, parameter named same as field!
health = health; // Which health is which? ๐
}
// Better: use 'this' to be clear
public void heal(int health) {
this.health = health; // "THIS object's health = parameter health"
}
}
When you call player1.heal(5), Java secretly passes player1 to the method as this. You can think of it like:
Think of it like this: You wrote a recipe (Player class), and now you can bake as many cookies (Player objects) as you want. Each cookie has its own ingredients (health, gold), but they all follow the same recipe!
// Define the blueprint once
public class Player {
int health;
int gold;
// ...constructor and methods as before...
}
// Create many different players from it
Player steve = new Player(20, 0); // Steve starts with 20 health, 0 gold
Player alex = new Player(20, 100); // Alex starts with 20 health, 100 gold
When steve.heal(5) runs, it only changes Steveโs health. Alexโs stats stay the same. Each object is independent, just like:
When we say Player p1 = new Player(...), we say p1 is an โinstanceโ of that class. Thatโs just fancy talk for โa house built from the blueprint.โ No big mystery!
The class is just the instructions (โPlayers have health and goldโ). The objects are the actual things we create using those instructions. Thatโs why we say โclass is the blueprint, objects are the houses.โ
One Last Thing: Notice how anyone can write p1.health = -999;? Thatโs not greatโplayers shouldnโt have negative health! If our game allows negative health, that could cause weird glitches like invincible players or healing that kills you. Weโll fix this by making variables private, letting only the Player class control how they change:
public class Player {
private int health; // Only Player methods can touch this now
private int gold; // This too!
// Methods control how these values change
public void heal(int amount) {
if (amount > 0) {
health += amount; // Only allow positive healing
}
}
}
In this section, we introduced the idea of creating a Player class to hold related stats (health, gold, etc.). Which statement best captures why this is beneficial for handling multiple players in a game?
public class Player {
---
int health;
---
public Player(int startHealth) {
---
health = startHealth;
---
}
---
public void heal(int amount) {
---
health += amount;
---
}
---
public static void main(String[] args) {
---
Player p = new Player(10);
---
p.heal(5);
---
System.out.println(p.health);
---
}
---
}
Checkpoint3.4.4.Short Answer: What Is the this Keyword?
In the code example, this appears inside heal to refer to the current objectโs fields (e.g., this.health). In 1-2 sentences, explain what this refers to when an instance method is called (e.g., p1.heal(5)).
Sample Solution: When we call p1.heal(5), this inside the heal method refers to p1. In other words, this is the specific Player object on which the method was invoked.
Checkpoint3.4.5.Reflection: Why No Return Type for a Constructor?
Java constructors look like methods but donโt have a return type. In 2-3 sentences, explain why constructors lack a void or Player return type. Hint: think about how new Player(...) already returns a fully constructed object without needing an explicit return statement.
Sample Solution: A constructorโs job is to initialize a new object. The new keyword allocates memory and then calls the constructor to set fields. By definition, constructors implicitly return the new object referenceโso Java syntax doesnโt require (or allow) a named return type.