Java • Object-Oriented Programming

Defining Classes — Define a class with fields and methods

Learn how to create your own data types by bundling variables and behaviors into reusable Java classes.

Java programming emblem with a coffee cup, code braces, and terminal
Inside this lesson 10 sections 5 questions 7 figures

SECTION 1

Historical Context & Motivation

Before object-oriented programming (OOP) became mainstream, programmers wrote code as long sequences of instructions that operated on separate data stored in variables. As programs grew larger — thousands, then millions, of lines — managing all that loose data became incredibly difficult. Bugs multiplied because any part of the code could accidentally change a variable that another part depended on. Developers needed a way to organize code into self-contained, reusable building blocks.

The idea of grouping data and behavior together into a single unit — a class — evolved over several decades. Today, Java is one of the most widely used OOP languages in the world, and defining classes is the very first skill you need to build anything meaningful in it.

1967 • Simula Introduces Classes

Norwegian computer scientists Ole-Johan Dahl and Kristen Nygaard create Simula, the first language to feature classes and objects, originally designed for simulations.

1983 • C++ Brings OOP to Systems Programming

Bjarne Stroustrup extends the C language with classes, creating C++ and proving that OOP can work in high-performance software.

1995 • Java Is Released

Sun Microsystems releases Java, a language designed from the ground up around classes and objects. Its "write once, run anywhere" philosophy makes OOP accessible to millions of developers.

2010s • OOP Dominates Industry

Java classes power Android apps, enterprise servers, and cloud platforms worldwide. Understanding how to define a class becomes a core skill in every Computer Science curriculum.

The central question that OOP answers is: How can we bundle related data and the actions that operate on that data into a single, reusable package? In Java, the answer is the class.

SECTION 2

Core Principles & Definitions

A class in Java is a blueprint or template that defines a new data type. It specifies what information an object of that type will hold and what actions it can perform. When you actually create an instance of a class using the new keyword, you get an object — a concrete realization of that blueprint living in your computer's memory.

1

Class

A blueprint that defines a new type. It declares fields (data) and methods (behavior). No memory is allocated until you create an object from it.
2

Field (Instance Variable)

A variable declared inside a class but outside any method. Each object gets its own copy of every field, storing the object's state — its specific data values.
3

Method

A block of code that performs an action. Methods define the object's behavior. They can read or modify the object's fields, accept parameters, and return values.
4

Object (Instance)

A specific instance of a class, created with the new keyword. Each object has its own field values but shares the same method definitions with all other instances of that class.
5

Constructor

A special method that runs when a new object is created. It typically initializes fields to starting values. Its name must match the class name exactly.
✦

KEY TAKEAWAY

Think of a class like a cookie cutter and objects like the cookies you stamp out with it. The cookie cutter defines the shape (fields and methods), but each cookie is its own independent item — you can frost one red and another blue. Similarly, each object carries its own data in its fields while sharing the same structure defined by the class.

SECTION 3

Visual Explanation — Anatomy of a Java Class

The diagram below shows the complete anatomy of a Java class called Dog. Notice how the class is organized into three distinct regions: the class header at the top, the fields in the middle, and the methods at the bottom.

Anatomy of a Java Classpublic class Dog {← CLASS HEADERFIELDS (State)private String name;private int age;private String breed;CONSTRUCTORpublic Dog(String name, int age, String breed) {this.name = name; this.age = age; this.breed = breed;}METHODS (Behavior)public String getName() { return name; }public void bark() {System.out.println(name + " says: Woof!");}}← CLOSING BRACE
The class header (blue) declares the class name. The fields (purple) store each object's data. The constructor (green) initializes objects. The methods (pink) define behaviors the object can perform.

Every Java class follows this basic structure. The public class Dog header tells the compiler we are defining a new type called Dog. Inside the curly braces, the three fields — name, age, and breed — represent the data each Dog object will carry. The methods getName() and bark() define what a Dog object can do. The constructor sits between the fields and methods, and it runs once every time you create a new Dog.

SECTION 4

How It Works — Syntax Deep Dive

Declaring Fields

A field declaration follows the pattern: accessModifier type fieldName;. The access modifier controls who can see and change the field. Using private is standard practice because it prevents outside code from directly changing an object's data — a concept called encapsulation.

FIELD DECLARATION PATTERN

accessModifiertypefieldName;accessModifier type fieldName;

accessModifier: private, public, or protected. type: any Java data type (int, double, String, etc.). fieldName: a descriptive name in camelCase.

Declaring Methods

A method declaration starts with an access modifier, then a return type (the kind of value it gives back), then the method name, then a pair of parentheses containing any parameters. If a method doesn't return a value, its return type is void. Parameters are like slots where you pass information into the method when you call it.

METHOD DECLARATION PATTERN

accessModifierreturnTypemethodName(parameterList)bodyaccessModifier returnType methodName(parameterList) { body }

returnType: the type of the value returned, or void if none. parameterList: zero or more type name pairs separated by commas. body: the statements that execute when the method is called.

The Constructor

A constructor looks like a method, but it has no return type and its name must be exactly the same as the class name. When you write new Dog("Max", 3, "Labrador"), Java calls the constructor, which assigns those argument values to the new object's fields. The keyword this refers to the current object being constructed, which is important when parameter names match field names.

CONSTRUCTOR PATTERN

publicClassName(parameterList)this.field=param;...public ClassName(parameterList) { this.field = param; ... }

The constructor has no return type — not even void. Use this.fieldName to distinguish the object's field from the parameter with the same name.

SECTION 5

Blueprint vs. Object — From Class to Instances

One of the most important distinctions in OOP is the difference between a class (the blueprint) and an object (a specific instance). You can create many objects from one class, and each object has its own independent set of field values. The diagram below shows how a single Dog class produces three distinct objects.

Class (Blueprint) → Objects (Instances)Dog (Class)Fields: name, age, breedMethods: getName(), bark()Constructor: Dog(...)new Dog(...)new Dog(...)new Dog(...)dog1name = "Max"age = 3breed = "Labrador"dog1.bark() → "Max says: Woof!"dog2name = "Bella"age = 5breed = "Poodle"dog2.bark() → "Bella says: Woof!"dog3name = "Rocky"age = 1breed = "Beagle"dog3.bark() → "Rocky says: Woof!"
One Dog class produces three independent objects. Each object stores its own field values (name, age, breed) but uses the same bark() method.

In the diagram, notice that dog1, dog2, and dog3 each have different values for name, age, and breed. When dog1.bark() is called, the method uses dog1's own name field, printing "Max says: Woof!". When dog2.bark() is called, it prints "Bella says: Woof!". Each object is self-contained, carrying its own state while sharing the behavior defined in the class.

SECTION 6

Worked Example — Building a Student Class

Let's build a complete Student class from scratch. This class will store a student's name and grades, and include a method that calculates their grade average.

Creating the Student Class

  1. 1

    Step 1 — Declare the Class

    Start with the class header. We use public class Student to define a new type called Student. The file must be saved as Student.java — in Java, the file name must match the public class name.
    public class Student { }
  2. 2

    Step 2 — Add Fields

    Identify what data a Student holds. We need a name (String) and an array of grades (double[]). We mark them private so only the class's own methods can access them directly.
    private String name; private double[] grades;
  3. 3

    Step 3 — Write the Constructor

    The constructor accepts a name and a grades array, then stores them in the object's fields using the this keyword. This ensures that when someone writes new Student("Alice", grades), the new object is properly initialized.
    public Student(String name, double[] grades) { this.name = name; this.grades = grades; }
  4. 4

    Step 4 — Add a Getter Method

    Since the fields are private, outside code needs a way to read them. A getter method returns the value of a field. Here, getName() returns the student's name.
    public String getName() { return name; }
  5. 5

    Step 5 — Add a Behavior Method

    Now add a method called getAverage() that loops through the grades array, sums the values, and divides by the number of grades. This returns a double.
    public double getAverage() { double sum = 0; for (double g : grades) { sum += g; } return sum / grades.length; }
  6. 6

    Step 6 — Create Objects and Test

    In a separate file with a main method, create a Student object and call its methods. The line Student s = new Student("Alice", new double[]{92, 88, 95}) creates the object, then s.getAverage() returns 91.666....
    Output: Alice's average is 91.67
⚠

Common Mistake

Forgetting the this keyword in the constructor when parameter names match field names. Without this, writing name = name; simply assigns the parameter to itself, leaving the field unchanged at its default value (null for Strings, 0 for numbers).

SECTION 7

Best Practices & Common Pitfalls

Writing classes that work is just the beginning — writing classes that are well-designed makes your code easier to debug, extend, and share with others. The table below compares good practices against common mistakes that new programmers make.

Best PracticeCommon PitfallWhy It Matters
Make fields privateMaking fields publicEncapsulation protects data from being changed in unexpected ways by outside code.
Provide getter and setter methodsAccessing fields directly from other classesGetters/setters let you add validation or change internal logic without breaking other code.
Use meaningful, camelCase namesUsing vague names like x, dataClear names make code self-documenting and much easier to read.
Write a constructor that initializes all fieldsLeaving fields at default values (null, 0)Uninitialized fields cause NullPointerExceptions and logic errors.
One class per file, file name matches class namePutting multiple public classes in one fileJava requires the file name to match the public class name — violating this causes compilation errors.

Best Practices vs. Common Pitfalls

✦

KEY TAKEAWAY

Think of encapsulation like a car dashboard. You interact with the steering wheel, pedals, and buttons (public methods), but you don't directly rewire the engine (private fields). The dashboard provides a controlled interface, and if the engine design changes, you can still drive the same way. Similarly, keeping fields private and providing methods to access them lets you change internal details without affecting the rest of your program.

SECTION 8

Connection to Advanced OOP Concepts

Defining a class with fields and methods is the foundation of object-oriented programming, but Java offers much more. Once you are comfortable building basic classes, you will encounter concepts that build directly on what you have learned here. The table below previews how today's lesson connects to future topics.

What You Learned TodayAdvanced ConceptWhat It Adds
Defining fields and methods in one classInheritanceCreate a new class that inherits fields and methods from an existing class, reducing code duplication.
Writing methods with specific return typesPolymorphismOverride inherited methods so different subclasses provide their own behavior for the same method name.
Making fields privateInterfaces & Abstract ClassesDefine contracts that multiple classes must follow, enforcing consistent behavior across unrelated types.
Storing data as instance fieldsStatic Fields & MethodsShare data or behavior across all instances of a class rather than each having its own copy.

From Basic Classes to Advanced OOP

Every one of these advanced topics starts with the same foundation: a class that has fields and methods. Mastering that structure now means you will be able to layer on inheritance, polymorphism, and interfaces without feeling lost. Think of this lesson as learning to build a sturdy single-story house — you will soon learn to add second and third floors on top of it.

SECTION 9

Practice Problems

Question 1: CONCEPTUAL

What is the difference between a class and an object in Java? Use an everyday analogy to explain your reasoning.
Show answer
A class is a blueprint or template that defines what data (fields) and behavior (methods) a type will have. An object is a specific instance of that class created with the new keyword, holding its own set of values. For example, a class is like an architectural blueprint for a house: it defines rooms and layouts, but you cannot live in a blueprint. Each house built from that blueprint is an object — they all have the same floor plan but can be painted different colors and furnished differently.

Question 2: BASIC CALCULATION

Given the following class, what will be printed when the code runs? public class Rectangle { private int width; private int height; public Rectangle(int width, int height) { this.width = width; this.height = height; } public int getArea() { return width * height; } } In main: Rectangle r = new Rectangle(5, 8); System.out.println(r.getArea());
Show answer
The output is 40. When new Rectangle(5, 8) is called, the constructor sets width to 5 and height to 8. The getArea() method returns width * height, which is 5 × 8 = 40. This is a straightforward example of how methods operate on the object's own field values.

Question 3: INTERMEDIATE

Write a complete Java class called BankAccount with: (a) a private String ownerName field, (b) a private double balance field, (c) a constructor that sets both fields, (d) a deposit(double amount) method that adds to the balance, and (e) a getBalance() method.
Show answer
public class BankAccount { private String ownerName; private double balance; public BankAccount(String ownerName, double balance) { this.ownerName = ownerName; this.balance = balance; } public void deposit(double amount) { balance += amount; } public double getBalance() { return balance; } } The class uses private fields for encapsulation. The deposit method modifies the balance field by adding the given amount. The getBalance method allows external code to read (but not directly change) the balance.

Question 4: APPLIED

A school grading app needs a Course class with fields for courseName (String), maxStudents (int), and enrolledCount (int). Write the class with a constructor and a method enroll() that only increases enrolledCount if the course is not already full. The method should return true if enrollment succeeded and false otherwise.
Show answer
public class Course { private String courseName; private int maxStudents; private int enrolledCount; public Course(String courseName, int maxStudents) { this.courseName = courseName; this.maxStudents = maxStudents; this.enrolledCount = 0; } public boolean enroll() { if (enrolledCount < maxStudents) { enrolledCount++; return true; } return false; } public int getEnrolledCount() { return enrolledCount; } } This class demonstrates how methods can include logic that protects the object's state. The enroll method checks whether the course is full before modifying the field, which is a real-world application of encapsulation — the class itself enforces the business rule rather than relying on outside code to check.

Question 5: CRITICAL THINKING

A programmer writes a Player class with public int health = 100; and no methods to modify it. Another part of the program accidentally sets player.health = -50;. Explain why this is a design problem, and redesign the class using private fields and a method that prevents health from dropping below zero.
Show answer
The problem is that making health public allows any code to set it to any value, including nonsensical ones like −50. This violates the principle of encapsulation. A better design is: public class Player { private int health; public Player() { this.health = 100; } public void takeDamage(int amount) { health -= amount; if (health < 0) { health = 0; } } public int getHealth() { return health; } } By making health private and controlling changes through the takeDamage method, the class guarantees that health can never be negative. This is why encapsulation is essential — it lets the class enforce rules about its own data, preventing bugs that would otherwise be difficult to track down.

SUMMARY

Lesson Summary

Summary

A class in Java is a blueprint that defines a new data type by bundling fields (instance variables that store an object's state) with methods (functions that define the object's behavior). Each class declaration follows the pattern public class ClassName { ... }, and a constructor initializes new objects when the new keyword is used. Fields should be private to enforce encapsulation, and getter/setter methods provide controlled access to data.

An object is a specific instance of a class, created at runtime with its own independent set of field values. You can create many objects from one class, each carrying its own state while sharing the same methods. This foundation — classes, fields, methods, constructors — is the starting point for all object-oriented programming in Java, including inheritance, polymorphism, and interfaces that you will study next.

Varsity Tutors • Java • Defining Classes — Define a class with fields and methods