Home

 › 

Articles

 › 

Understanding Class In Java, With Examples

OOPs in Java

Understanding Class In Java, With Examples

In Java, classes are a collection of attributes and behaviors that are used to maintain better order in a program. We call these attributes and behaviors fields and methods. However, if you have experience with other programming languages, they can be likened to variables and functions, respectively. The only difference is that they are contained within a class. 

Hello World

This may look familiar:

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

The above code is a simple hello world program in Java. You may notice that the entire program is contained within a class! We call this class HelloWorld, and it has a method, or behavior, that we named main.

In this example, we follow the convention of having no return value (void), also taking in a string array of program arguments. Keywords such as public and static simply modify the method, but we can ignore these for now.

When you run this Java file, the main method is called internally, and this allows a programmer to dictate what the program does when it begins.

Object-Oriented Programming

Every program is contained within a class for an important reason: Java is an object-oriented programming language. Just as it sounds, the structure and function of every Java program is based around the idea of classes and how they can be used to accomplish tasks with more depth.

object oriented programming
OOL and OOP are used interchangeably.

Creating Classes

Fields

Since classes contain attributes and behaviors to model some kind of entity, you can almost think of it as a blueprint. Let’s look at an example of how we can use classes to represent a car in Java. We can first start out with its attributes:

public class Car {
    String make;
    String model;
    int year;
    double price;

We will see how we can use these attributes to our advantage later. For now, notice what we are doing at a high level. Just as a car in real life would have a make, model, year, and price, we can define a blueprint of a car that has these properties, making sure to use the correct data types for each one. As with the main method, ignore the public keyword for now.

Methods

Now that we have the attributes of the car, what can we do with it? Let’s create a simple method that will print out the car’s properties:

    public void displayInfo() {
        System.out.println("Make: " + make);
        System.out.println("Model: " + model);
        System.out.println("Year: " + year);
        System.out.println("Price: $" + price);
    }

Constructors

With all the proper attributes and a new method to display them, we have a great start to our blueprint. However, a blueprint is useless on its own — so how do we use it? Similar to real life, a class can be used as an outline for creating an instance of the represented object. In fact, we often call this instantiating the class. To instantiate a class, we must first define a special method called the constructor. We can do this like so:

   public Car(String make, String model, int year, double price) {
        this.make = make;
        this.model = model;
        this.year = year;
        this.price = price;
    }

When we write the method, we indicate it is the constructor by using the name of the class. Note that in this case, we take in all the desired attributes of the car as parameters to the constructor. By doing this, we make it easy to initialize a new car instance with arbitrary properties. The body of this constructor simply assigns the specific object’s properties to the ones given as parameters. The this keyword is extremely important, and we will talk about it more soon.

Using Classes

Instantiating an Object

With the constructor finished, we can now create arbitrary Car objects like so (in a different java file):

Car carObject = new Car("Nissan", "Altima", 2005, 3768.00);

There are some important details to note in this line. Car simply states the data type of the variable. It is the same as having something like String, but instead of it being a built-in class, we created it. However, on the right side of the equals, we can see something different: the new keyword. 

When you, for example, assign the number five to an integer, it is a relatively simple operation. However, when you instantiate a new object, there is more going on. The new keyword indicates that you are calling a constructor method. Then, you can use that method, and it returns a newly-created Car object that carObject will, in this case, be assigned to.

Using Fields and Methods

With our new Car object, we can do whatever we wish with its fields and methods. For example, we can call displayInfo:

carObject.displayInfo();
/*    Make: Nissan
  Model: Altima
  Year: 2005
  Price: $3768.0*/

If we wish, we can also directly modify its fields:

carObject.make = "Ford";

The this Keyword

What does this do?

Recall the constructor used for the Car class:

    public Car(String make, String model, int year, double price) {
        this.make = make;
        this.model = model;
        this.year = year;
        this.price = price;
    }

At first glance, this may be confusing. Usually, when we make a constructor, we use the same name for the fields and parameters. While this does make it more straightforward to write, it can make the purpose of it unclear to beginners.

In reality, the function of this constructor is quite simple. When we created a Car object, we wrote the following: 

Car carObject = new Car("Nissan", "Altima", 2005, 3768.00);

As can clearly be seen, the values we pass in line up with the parameters in the constructor. Therefore, when we just write make, model, year, or price, we are referring to the values we passed in. However, when we use the this keyword, this refers to the object that is being created. When, for example, we write this.make, we refer to the current object’s make field. This constructor simply assigns each field of the new Car object to the passed-in values.

Constructors Can Do Anything

You have complete freedom when writing constructors in Java. In addition to assigning fields, you can have any code you want to be run when creating a new object. Also, not all of the fields need to have a respective argument in the constructor. If you wanted this.make to always be Ford, then you could just as easily have a constructor like so:

    public Car(String model, int year, double price) {
         this.make = "Ford";
        this.model = model;
        this.year = year;
        this.price = price;
    }

The this keyword is important to understand, as it is used heavily in both the constructor and any other method you may create. Just know that it can be treated like any other object, and it refers to the object in the current context.

Getters and Setters

Earlier, we directly modified an object’s field using this line:

carObject.make = "Ford";

While this is valid code, it is not best practice to do this in Java. Instead of directly retrieving or assigning an object’s field, we use special methods called getters and setters.

Function Overloading in C++
To retrieve or set an object’s field, we use special methods called getters and setters.

Here’s how we might write the getters and setters for our Car class:

   public String getMake() {
        return make;
    }

    public void setMake(String make) {
        this.make = make;
    }

    public String getModel() {
        return model;
    }

    public void setModel(String model) {
        this.model = model;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

If these methods seem pretty simple, that’s because they are. Any getX method returns the value of the object’s X field, and any setX method takes in a value and sets the object’s X field to that value. Therefore, instead of using the aforementioned line, you could write:

carObject.setMake("Ford");

Why do we use them?

While the function of these methods is apparent, their purpose may not be. Why do we have these methods if they’re so simple? Why not just act on the fields directly? Well, it’s true that they are often not necessary, but sometimes they are incredibly useful.

Sometimes, when you set a field, other parts of the object must be modified as well. Other times, more processing must be done before retrieving a field. It can also be useful for validation.

As a more concrete example, let’s say you have written a Person class, and they have an age field. Obviously, you cannot have a negative age or an age that’s over 1,000. Therefore, in the setAge method, you can check if the age lies within a certain range before setting it, and this could prevent issues later on in the program.

Wrapping Up

For reference, here is the completed class:

public class Car {
    // Fields
    String make;
    String model;
    int year;
    double price;

    // Constructor
    public Car(String make, String model, int year, double price) {
        this.make = make;
        this.model = model;
        this.year = year;
        this.price = price;
    }

    // Method to display all fields
    public void displayInfo() {
        System.out.println("Make: " + make);
        System.out.println("Model: " + model);
        System.out.println("Year: " + year);
        System.out.println("Price: $" + price);
    }

    // Getters and setters
    public String getMake() {
        return make;
    }

    public void setMake(String make) {
        this.make = make;
    }

    public String getModel() {
        return model;
    }

    public void setModel(String model) {
        this.model = model;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}

This article covers only the essentials of classes in Java, and there is much more to learn. I encourage you to learn more advanced concepts, such as object-oriented programming and computer science concepts, to deepen your knowledge!

Frequently Asked Questions

What is a class in Java?

A class in Java is a blueprint for creating objects. It includes fields (variables) and methods to define the state and behavior of its objects.

 

 

 

What is an object in Java and how is it related to a class?

An object in Java is an instance of a class. It is created using the ‘new’ keyword, and it inherits the properties and behavior defined by the class.

How do you declare a class in Java?

You declare a class in Java using the ‘class’ keyword, followed by the name of the class, and a pair of curly braces {}. For example: public class MyClass {}. You can add fields and methods within the curly braces as needed.

What is the difference between a class and an object in Java?

A class is a blueprint or template that describes the behavior/state that objects of its type support, while an object is an instance of a class.

What is a nested class in Java and why would you use it?

A nested class is a class declared within another class. They are used for logical grouping of classes that are only used in one place, which increases encapsulation and makes the code more readable and maintainable.

To top