The variable types that Java provides by default are almost always inadequate to represent complex data. Additionally, you may want to group multiple related variables and methods together. To solve these problems, Java lets us create classes and objects.

A class is a blueprint that Java uses to group variables and methods together into one single unit.

public class <class name> {
	// For instance variables
	<access modifier> <type> <variable name>;
	<access modifier> <type> <variable name> = <value>;
	
	// For methods
	<access modifier> <return type> <method name>(<parameter list>) {
		<code>
	}
}

The class name is the name used when defining what type a variable will have. If a class had the name Elevator, declaring a variable that holds an elevator would be

Elevator <variable name>;

Class names are PascalCase, which is the same as camelCase but with the first letter capitalized. The file that defines the class also has to have the same name as the class, so in the case of the Elevator class, the file name would be Elevator.java.

The <access modifer> field is usually one of two: public or private. If an instance variable or method is public, it can be accessed from outside the class. Conversely, if a variable or method is private, only code inside of the class can use it. By using the correct access modifiers, usage of the class by other people or yourself in the future is much easier because it condenses all of the functionality of the class down into a few variables and methods.

public class Elevator {
	private int currentFloor = 0;
	
	public void goToFloor(int floor) {
		// Ensure that the requested floor is valid (1 to 10)
		if (floor > 0 && floor <= 10) {
			// Methods in the class can access the variables in the class
			currentFloor = floor; 
		}		
	}
	
	public int getCurrentFloor() {
		return currentFloor;
	}
}

Now to use the elevator class

// Create a new instance of the Elevator class
Elevator elevator = new Elevator();

elevator.goToFloor(4);
System.out.println(elevator.getCurrentFloor()); <- Prints 4

// ERROR: you cannot assign to a private variable outside of the class
elevator.currentFloor = 2;

It is best practice to declare all instance variables as private and create methods to get and/or set the value, adding guardrails to ensure proper use of the class.

An instance is the physical layout in memory built from the class blueprint. All of the variables and methods live together in the instance. To create a new instance, the new operator is used.

Elevator elevator = new Elevator(); <- Creates a new instance of Elevator

If you create two instances of the same class, they will not share the same values in their instance variables.

Elevator elevatorA = new Elevator();
Elevator elevatorB = new Elevator();

elevatorA.goToFloor(2);
System.out.println(elevatorA.getCurrentFloor()); <- Prints 2
System.out.println(elevatorB.getCurrentFloor()); <- Prints 0

If a method in the class has a parameter with the same name as an instance variable, Java will use the parameter. To access an instance variable with the same name as a parameter, use the this keyword. Think of this as a variable that holds the current instance of the class.

public class Elevator {
	private Distance position;
	
	public setPosition(Distance position) {
		System.out.println(position); <- Prints the value from the parameter
		
		// Assigns the parameter to the instance variable
		this.position = position;
	}
}