L10: Introduction to Writing Classes Pt.1
Overview
In this chapter, we’ll dive into the fundamentals of writing classes in Java, focusing on how to design and implement basic class structures, how to identify and declare instance variables, and how to write constructors and methods. By the end of this guide, you’ll have a clear understanding of how to build reusable, modular classes that encapsulate data and behavior effectively.
Introduction
Classes form the backbone of Java’s object-oriented programming (OOP). They allow you to create reusable blueprints to represent complex concepts, tying data and behaviors together. While we’ve previously worked with client classes like Scanner
and String
, those were built-in classes. The goal now is to create our own custom classes, also called instantiable classes, where we define both the data (state) and behaviors (actions) ourselves.
Key Points:
- Modularity: Classes encapsulate functionality, making code reusable and easier to maintain.
- Customization: Writing custom classes allows for more control over how objects behave compared to using predefined classes.
Identifying Data and Behaviors
Before writing a class, you need to determine:
- Data (Attributes/State): These are the properties of an object.
- Behaviors (Methods): These are the actions that the object can perform.
For example, let’s build a class for an insect. The attributes of the insect could include its weight
, and its position in the world (x
and y
coordinates). Its behaviors might include move
and eat
.
public class Insect {
private double weight; // Data
private int x, y; // Data
public void move() { // Behavior
// Method logic for moving
}
public void eat() { // Behavior
// Method logic for eating
}
}
Instance Variables
Instance variables store the state of an object. Each object of a class has its own copy of these variables. This means that every instance of the Insect
class has its own values for weight
, x
, and y
.
Instance variables are declared at the class level, outside any methods, making them accessible to all methods of the class.
public class Insect {
private double weight; // Instance variable
private int x, y; // Instance variable
}
In memory, each object gets its own space in the heap, where it stores its instance variables.
Heap Memory
┌────────────────────────────────────────────────────┐
│ Insect 1 (Object Reference) │
│ ┌───────────┐ ┌────────────┐ ┌───────────┐ │
│ │ weight: 5 │ │ x: 10 │ │ y: 20 │ │
│ └───────────┘ └────────────┘ └───────────┘ │
│ │
│ Insect 2 (Object Reference) │
│ ┌───────────┐ ┌────────────┐ ┌───────────┐ │
│ │ weight: 3 │ │ x: 15 │ │ y: 25 │ │
│ └───────────┘ └────────────┘ └───────────┘ │
│ │
│ Insect 3 (Object Reference) │
│ ┌───────────┐ ┌────────────┐ ┌───────────┐ │
│ │ weight: 8 │ │ x: 12 │ │ y: 30 │ │
│ └───────────┘ └────────────┘ └───────────┘ │
└────────────────────────────────────────────────────┘
classDiagram class Insect { -double weight -int x -int y +move() +eat() }
Visibility Modifiers (public and private)
Visibility modifiers control access to class members (variables and methods). In Java, the two most common visibility modifiers are:
private
: Members can only be accessed within the same class.public
: Members can be accessed from other classes.
public class Insect {
private double weight; // Only accessible within Insect
public void move() { // Accessible to other classes
// Move logic
}
}
The principle of encapsulation ensures that an object controls its own state. By making instance variables private, you ensure that external classes cannot directly manipulate an object’s state.
Testing Objects
To create an object, use a client class or add a main
method directly in your class.
public class TestInsect {
public static void main(String[] args) {
Insect bee = new Insect(); // Create an Insect object
bee.move(); // Call method
}
}
Constructors
A constructor is a special method that initializes a new object. Every time an object is created, its constructor is called. Java provides a default constructor if none is defined, but you can also create custom constructors to initialize variables with specific values.
Default Constructor
public class Insect {
public Insect() {
// Default constructor
weight = 1.0; // Default weight
x = 0; // Default x-coordinate
y = 0; // Default y-coordinate
}
}
Custom Constructor
public class Insect {
public Insect(double initialWeight, int startX, int startY) {
weight = initialWeight; // Set initial weight
x = startX; // Set initial x-coordinate
y = startY; // Set initial y-coordinate
}
}
Methods
Methods define the behaviors of an object. Methods can either manipulate the state (non-static) or provide utility functionality (static). In our Insect
class, move()
and eat()
are examples of methods.
public void move() {
// Logic to change x and y coordinates
}
public void eat() {
// Logic to increase weight
}
Static Variables and Constants
Static variables are shared across all instances of a class, meaning there is only one copy in memory. Constants are defined using the final
keyword.
public class Insect {
private static final double MAX_WEIGHT = 100.0; // Constant
}
More on Static Methods
Static methods belong to the class rather than instances of the class. For example, a utility method to generate random values can be static.
public static int getRandomCoordinate() {
return (int)(Math.random() * 100); // Generate random coordinate
}
Knowledge Check
- What is an instance variable?
An instance variable is a variable defined at the class level and is specific to each instance (or object) of the class. Each object of the class has its own unique copy of the instance variables, which hold the object’s state or attributes. - What does the
private
visibility modifier do?
Theprivate
visibility modifier restricts access to a class member (variable or method) so that it can only be accessed within the same class. It prevents external classes from directly accessing or modifying the member, helping to encapsulate the class’s internal state. - How are static methods different from non-static methods?
Static methods belong to the class itself, not to any specific instance of the class. They can be called without creating an object of the class and typically provide utility functions. Non-static methods, on the other hand, operate on individual objects and can access instance variables specific to the object. - Why do we use constructors in a class?
Constructors are used to initialize the state of an object when it is created. They set the initial values of the instance variables and ensure that the object is in a valid state when it starts being used. - Can you write a constructor with parameters?
Yes, a constructor can accept parameters to set initial values. - What are instance variables?
Instance variables are variables declared at the class level, specific to each object of the class. - Why should instance variables be private?
To protect the internal state of objects and ensure that only methods within the class can modify them.