Java is the most popular programming language in the world, it is also very heavily object orientated (OO). It is recommended that you read my previous tutorial that introduces the concept of object orientated programming (OOP).

This tutorial assumes basic programming knowledge in any language, including ideas like variables and basic C-like syntax.

You must also have the Java Development Kit installed.

Hello, World!

The first thing to do when learning any language is making a “Hello, World!” program. In Java, this can be done as follows:

1. Declare a Class

Java classes can be declared using the class keyword as follows: public class {Class Name}. It is convention in Java that classes must be in title case, meaning that each word must be appended and the first letter must be capitalized like HelloWorld.

2. Add a Main Method

To be able to run a program, the Java executor must know where to begin. This is where the main method comes in. In Java, the main method must have a signature of public static void main(String[]).

3. Print!

In Java, typical console output is done using the System.out.println() method. In our case we can call System.out.println("Hello, World!").

Your final code should look like

public class HelloWorld {
	public static void main(String[] args) {
		System.out.println("Hello, World!");
	}
}

Save this file as HelloWorld.java, run the command javac HelloWorld.java to compile it and java HelloWorld to run it.

OOP

Now we have learned the basics of writing Java code, we can move on to writing OO code. In my previous article, I explained Object Orientation using a basketball. Now, lets use that example again in our Java code.

Lets first start with just the barebones Java class:

public class Basketball {
	// To be implemented.
}

Instance Variables (Properties)

In my previous tutorial, I listed some properties that all basketballs have: size, number of bounces, color, and location.

Before we can implement these, we must first think of the data type that each of them must be. The size and number of bounces can be represented by int values. The color can be represented in many ways, but for simplicity, lets represent it using a String. The location on the other hand is more complicated. In 2D space, a location can be represented with a x and y axis. Ignoring the fact that the world is 3D, we can represent the location with two int instance variables: locationX and locationY.

This gives us the following code:

public class Basketball {
	int size;
	int numberOfBounces;
	String color;
	int locationX;
	int locationY;
}

Notice the capitalization of the variable names. This is because in Java, variables should be named in camelCase.

⚠️ Encapsulation

The previous piece of code is not strictly correct in Java. This is because Java uses encapsulation, which means that instance variables should never be accessed or modified directly. Rather, the class should provide accessor/mutator methods, better known as get and set methods. The philosophy behind this is that in the case when the class is updated, the client classes (other classes that use the class) shouldn’t also break. If we use accessor/mutator methods, any changes internal to the class wouldn’t affect any client classes. Accessor methods and mutator methods can easily be named by prepending get or set to the variable’s name and adjusting capitalization.

The correct code would thus be:

public class Basketball {
	private int size;
	private int numberOfBounces;
	private String color;
	private int locationX;
	private int locationY;

	public int getSize() {
		return size;
	}

	public int getNumberOfBounces() {
		return numberOfBounces;
	}

	public String getColor() {
		return color;
	}

	public void setColor(String newColor) {
		this.color = newColor;
	}

	public int getLocationX() {
		return locationX;
	}

	public int getLocationY() {
		return locationY;
	}
}

Private vs Public

You might have noticed that each method header declares that the method is public and each instance variable declares that it is private. public instance variables and methods allow any class to access or call the variable/method, while private instance variables and methods can only be accessed or called inside the same class. private instance variables/methods are also the primary way to hide the implementation of a given class from other classes and are thus used in encapsulation to prevent other classes from accessing the class’ instance variables.

By default, instance variables are public.

Behaviors (Methods)

You might have noticed that there are quite a few mutator methods missing from that previous piece of code. This is because some internal variables are tied to behaviors, and can not be instantly changed. For example, you can’t magically bounce a basketball more than once at a time. Some behaviors must be relative to the object’s current state. For example, a basketball can only move relative to its current location and can only inflate or deflate relative to its current size.

For our case, a basketball can bounce (increase the number of bounces), inflate (increase size), deflate (decrease size) and move (move location relative to current location).

Thus, our code would be

public class Basketball {
	private int size;
	private int numberOfBounces;
	private String color;
	private int locationX;
	private int locationY;

	public int getSize() {
		return size;
	}

	public int inflate(int amount) {
		size += amount;
		return size;
	}

	public int deflate(int amount) {
		size -= amount;
		return size;
	}

	public int getNumberOfBounces() {
		return numberOfBounces;
	}

	public int bounce() {
		return ++numberOfBounces; // increase number of bounces and return the new number
	}

	public String getColor() {
		return color;
	}

	public void setColor(String newColor) {
		this.color = newColor;
	}

	public int getLocationX() {
		return locationX;
	}

	public int getLocationY() {
		return locationY;
	}

	// amounts can be negative to allow for movement left on the X axis or up on the Y axis.
	public void move(int amountX, int amountY) {
		locationX += amountX;
		locationY += amountY;
	}
}

Constructors

A constructor is a special method that allows you to initiate an object with specific values during creation. The special thing about a constructor is that it has no return value, not even void. It cannot be directly called by any other non-constructor method.

A full constructor for our Basketball class would look like:

public Basketball(int bSize, String bColor, int bLocationX, int bLocationY) {
	size = bSize;
	color = bColor;
	locationX = bLocationX;
	locationY = bLocationY;
}

Final Basketball Code

Our final code should look like:

public class Basketball {
	private int size;
	private int numberOfBounces;
	private String color;
	private int locationX;
	private int locationY;

	public Basketball(int bSize, String bColor, int bLocationX, int bLocationY) {
		size = bSize;
		color = bColor;
		locationX = bLocationX;
		locationY = bLocationY;
	}
	public int getSize() {
		return size;
	}

	public int inflate(int amount) {
		size += amount;
		return size;
	}

	public int deflate(int amount) {
		size -= amount;
		return size;
	}

	public int getNumberOfBounces() {
		return numberOfBounces;
	}

	public int bounce() {
		return ++numberOfBounces; // increase number of bounces and return the new number
	}

	public String getColor() {
		return color;
	}

	public void setColor(String newColor) {
		this.color = newColor;
	}

	public int getLocationX() {
		return locationX;
	}

	public int getLocationY() {
		return locationY;
	}

	// amounts can be negative to allow for movement left on the X axis or up on the Y axis.
	public void move(int amountX, int amountY) {
		locationX += amountX;
		locationY += amountY;
	}
}

Testing Our Code

Now that we have finished implementing the Basketball class, lets test it!

To test our code, lets implement a class with a main method, which creates instances of the Basketball class and tests each method.

First, lets test the constructor and each get method:

public class TestBasketball {
	public static void main(String[] args) {
		// test constructor
		Basketball test = new Basketball(10, "red", 4, 3);

		// test get methods.
		System.out.println("Test #1");
		System.out.println("Initial Basketball has size " + test.getSize());
		System.out.println("Initial Basketball has " + test.getNumberOfBounces() + " bounces.");
		System.out.println("Initial Basketball has color" + test.getColor());
		System.out.println("Initial Basketball has x location " + test.getLocationX() + " and y location " + test.getLocationY());
		System.out.println("\n\n");

	}
}

Next, we can test the mutator methods:

public class TestBasketball {
	public static void main(String[] args) {
		// test constructor
		Basketball test = new Basketball(10, "red", 4, 3);

		// test get methods.
		System.out.println("Test #1");
		System.out.println("Initial Basketball has size " + test.getSize());
		System.out.println("Initial Basketball has " + test.getNumberOfBounces() + " bounces.");
		System.out.println("Initial Basketball has color" + test.getColor());
		System.out.println("Initial Basketball has x location " + test.getLocationX() + " and y location " + test.getLocationY());
		System.out.println("\n\n");

		// test mutator methods
		System.out.println("Test #2");
		System.out.println("Basketball inflated to " + test.inflate(4));
		System.out.println("Basketball deflated to " + test.deflate(3));
		test.bounce();
		test.bounce();
		System.out.println("Basketball bounced " + test.getNumberOfBounces() + " times");
		test.setColor("dark red");
		System.out.println("Basketball is now " + test.getColor());
		test.move(10, 41);
		System.out.println("Basketball now has x location " + test.getLocationX() + " and y location " + test.getLocationY());

		System.out.println("Tests done.");
	}
}

Save this file as Test.java in the same folder as the Basketball.java. Now, compile and run Test.java.

🎉 Tada!

Now we’ve learned the basics of creating classes in Java, we can now move on to more advanced ideas in part two of my tutorial on OOP in Java.