Free for students · Ad-free · WCAG 2.1 AA Compliant · Accessibility

Objects: Instances of Classes

Lesson ~10 min read 8 MCQs

In simple terms: In simple terms, a class is like a blueprint for a house, and an object is the actual, unique house you build from that blueprint.

Why this matters

Think about your favorite role-playing game. When you start, you don't just get a generic character. You go to a character creation screen. That screen is a template, right? It has fields for a name, a class (like a warrior or a mage), hair color, and starting stats.

The game designers built one blueprint for what a character can be. But you, Maya, Carlos, and every other player use that blueprint to create your own specific character. Your character, "ShadowSlayer," is a unique instance. Maya's character, "Sunfire," is another. They were both made from the same template, but they are separate, individual entities in the game world.

That's the core idea we're exploring today: the difference between a blueprint (a class) and the actual thing you create from it (an object). We'll see how Java uses this powerful concept to build everything from simple data entries to complex game characters.

Class vs. Object: Blueprint vs. Instance

Concept overview

classDiagram
  Object <|-- Vehicle
  Vehicle <|-- Car
  Vehicle <|-- Truck
  class Object{
    ...
  }
  class Vehicle{
    +int speed
    +int numWheels
    +startEngine()
  }
  class Car{
    +int numDoors
  }
  class Truck{
    +double towingCapacity
  }
This class diagram illustrates an inheritance hierarchy. The `Object` class is the ultimate superclass. The `Vehicle` class inherits from `Object`, and the `Car` and `Truck` classes both inherit from the `Vehicle` class, gaining its attributes and methods.

Core explanation

Welcome! Let's dive into the heart of object-oriented programming. It sounds complicated, but I promise it's an idea you already understand from real life.

The Blueprint and the Building

The single most important analogy for this topic is the blueprint.

Imagine an architect in Chicago designs a blueprint for a new type of eco-friendly townhouse. That blueprint is incredibly detailed. It specifies the number of bedrooms, the type of windows, the layout of the kitchen, and the materials for the roof. The blueprint itself is not a house. You can't live in a blueprint.

A class in Java is exactly like that blueprint. It's a template that defines the attributes (data) and behaviors (methods) that objects of its type will have.

class Dog {
    // Attributes (the data)
    String name;
    String breed;
    int age;
    boolean isGoodBoy;

    // Behaviors (the methods - what the Dog can DO)
    void bark() {
        System.out.println("Woof!");
    }

    void celebrateBirthday() {
        age = age + 1;
    }
}

Here, the Dog class is our blueprint. It says that any Dog we create will have a name, a breed, an age, and a good-boy status. It also says any Dog will be able to bark() and celebrateBirthday().

The `Dog` Class Blueprint

Now, what's an object? An object is the actual house built from the blueprint. You can take that one townhouse blueprint and build a whole neighborhood. Each house is a distinct object. They all share the same design, but each one has its own specific address, its own family living inside, and maybe a different color front door. They are instances of the blueprint.

In Java, we create an object (an "instance" of a class) using the new keyword. This process is called instantiation.

// This line creates a new Dog object from the Dog class
Dog myDog = new Dog();

Declaring Variables for Objects

Let's break that line down, because every part is important.

Dog myDog = new Dog();

  • Dog: This is the type. We're declaring that the variable we're about to create will refer to an object of the Dog class.
  • myDog: This is the variable name. It's our label for the object.
  • =: The assignment operator.
  • new Dog(): This is the magic. The new keyword tells Java's virtual machine to allocate memory for a brand new Dog object. Dog() is the constructor, a special method that creates and initializes the object. We'll talk more about constructors soon!

This covers one of our key goals: developing code to declare variables that store these kinds of objects, which are called reference types.

Tracing Object Instantiation

The Remote Control: Understanding References

When you create a variable for a primitive type like int, the variable holds the value directly.

int score = 95;

The box in memory labeled score literally contains the number 95.

Object variables work differently. The variable does not hold the object. It holds a reference to the object. Think of it as holding the memory address where the object lives.

A better analogy is a TV remote.

Dog myDog = new Dog();

The myDog variable is not the dog. It's a remote control that is tuned to the specific Dog object you just created in memory. If you want the dog to bark, you use the remote: myDog.bark().

This distinction is critical. A variable of a reference type holds an object reference, which is like the memory address of that object.

A Peek into Inheritance

Now, let's add one more layer. In the real world, we categorize things. A Golden Retriever is a specific type of Dog. A Dog is a specific type of Mammal. A Mammal is a specific type of Animal.

Java does this too, using inheritance.

We can create a general "blueprint" and then have more specific "blueprints" that inherit all the features of the general one.

  • The general blueprint is called a superclass.
  • The specific blueprint is called a subclass.

Let's say we have a Vehicle class. All vehicles have a speed and a number of wheels.

class Vehicle {
    int speed;
    int numWheels;

    void go() {
        // code to make it move
    }
}

Now, we can create a Car class that extends Vehicle. This means it automatically gets all of Vehicle's attributes and methods, and can add its own.

// Car is a subclass of Vehicle
class Car extends Vehicle {
    int numDoors; // A car-specific attribute
}

Because Car is a subclass of Vehicle, any Car object will have speed, numWheels, a go() method, and numDoors. This saves us from rewriting code and helps organize our programs logically.

Finally, a key fact to know for the AP exam: All classes in Java, whether you write it or not, are automatically subclasses of the master Object class. The Object class is the great-great-grandparent of every single object in Java. It provides some basic functionality that all objects share.

See it in action

python
Line 1
Output
Click Run to see the output.

        
Try these
    © Shrutam.ai

    Worked examples

    Let's make this concrete. Seeing the code in action is the best way to solidify these ideas.

    Example 1: Creating GamePlayer Objects

    Problem: You're building a simple game. You need a way to represent players. A player has a username (a String) and a score (an int). Write the code to define a GamePlayer class and then create two distinct player objects for "Aaliyah" and "Jordan".

    Solution Walkthrough:

    1. 1
      Define the Blueprint (the Class)
      First, we need to create the GamePlayer.java file. This class will define what it means to be a player.
      public class GamePlayer {
          String username;
          int score;
      }

      This is our blueprint. It says every GamePlayer will have a String for their name and an int for their score.

    2. 2
      Instantiate the Objects
      Now, in another file with our main method (like GameRunner.java), we can create the actual players.
      public class GameRunner {
          public static void main(String[] args) {
              // Create the first player object
              GamePlayer player1 = new GamePlayer();
              player1.username = "Aaliyah";
              player1.score = 1500;
      
              // Create the second player object
              GamePlayer player2 = new GamePlayer();
              player2.username = "Jordan";
              player2.score = 1250;
      
              System.out.println("Player 1: " + player1.username + ", Score: " + player1.score);
              System.out.println("Player 2: " + player2.username + ", Score: " + player2.score);
          }
      }

    Why it Works: We used the GamePlayer class blueprint twice. The line GamePlayer player1 = new GamePlayer(); created the first object in memory, and the player1 variable now holds the "remote control" to it. We then used that remote (player1.username = ...) to set its specific attributes. We did the exact same thing for player2, creating a completely separate object in a different spot in memory.

    Two `GamePlayer` Objects in Memory
    Example 2

    The "One Remote, Two Pointers" Problem

    Problem: You have one Book object. You create a second Book variable and assign the first variable to it. What happens when you change the book's title using the second variable?

    The 'One Remote, Two Pointers' Problem

    Solution Walkthrough:

    1. Define the Book Class: A simple class with a title.

      public class Book {
          String title;
      }
    2. Create the Scenario: In our main method, let's run the experiment.

      public class Library {
          public static void main(String[] args) {
              // 1. Create ONE book object.
              Book favoriteBook = new Book();
              favoriteBook.title = "The Great Gatsby";
      
              // 2. Create a second variable.
              // This does NOT create a new object!
              Book bookOnLoan = favoriteBook;
      
              // 3. Let's check their titles.
              System.out.println("Favorite Book Title: " + favoriteBook.title); // Prints "The Great Gatsby"
              System.out.println("Book on Loan Title: " + bookOnLoan.title);   // Prints "The Great Gatsby"
      
              // 4. Now, change the title using the second variable.
              bookOnLoan.title = "To Kill a Mockingbird";
      
              // 5. What is the title of the *original* book variable now?
              System.out.println("Favorite Book Title after change: " + favoriteBook.title);
          }
      }

    Result and Explanation: The final line will print: Favorite Book Title after change: To Kill a Mockingbird.

    Why? This is a classic AP question. The line Book bookOnLoan = favoriteBook; does not copy the object. It only copies the reference (the remote control). You now have two remotes (favoriteBook and bookOnLoan) pointing to the exact same Book object in memory. When you use one remote to change the channel (the title), anyone looking at the TV (the object) will see the change, no matter which remote they used.

    Try it yourself

    Ready to try on your own? Don't worry about getting it perfect; the goal is to think through the process.

    1. Design a Playlist Class: You're building a music app. You need a class to represent a user's playlist.

      • What attributes would a Playlist object need? Think of at least two (e.g., its title, the creator's name, a list of songs).
      • Write the Java code for the Playlist class definition.
      • In a main method, write the single line of code that declares a Playlist variable named summerVibes and instantiates a new Playlist object for it.
    2. Inheritance Puzzle:

      • Imagine you have a Person superclass.
      • You then create two subclasses: Student and Teacher.
      • If the Person class has an attribute String name, will an object created from the Student class have a name? Why or why not?
    Inheritance: `Person`, `Student`, and `Teacher`