Learn Java Easy. Chapter 19. Functions and OOP

Chapter 19. Functions and OOP in Java

Chapter 19. Functions and OOP in Java

Functions and OOP

Before moving to the final phase of our plan, you need to understand a couple more things. I’m referring to functions and object-oriented programming exercises. By now you already master the syntax, but you program in a linear way. We’ve only done programs within the Main class. In real programs it’s impossible to find that linearity. Programs reuse code and this is stored in different classes. Afterwards, from the Main class they are called and executed depending on the order in which we need them.

We’re going to learn how to reuse code and work with different classes; for this, we’ll start with functions and methods. In Java, the terminology for “methods” and “functions” can be a bit confusing, especially if you come from other programming languages. In Java terms:

Method: It’s a function that is defined within a class. In Java, all functions must be within a class, so all functions in Java are methods. The term “method” is more common in Java.

Function: It’s a more general term and is used in many programming languages to refer to a block of code that performs a specific task. In Java, it refers to the same as a method, but is used less frequently.

Difference between public, protected or private

public: A method or variable that is declared as public can be accessed from any other class. It doesn’t matter which package it’s in. We use it when we want the method or variable to be globally available.

When a method or variable is declared as private, then it will only be accessible within the same class in which it is defined. It is used to protect data from external access.

Finally, a method or variable protected is accessible within the same package and by subclasses, even if they are in different packages.

Difference between methods that return a value and “void” methods

  • Methods that return a value: These methods specify a return type (for example, int, String, boolean, etc.) in their declaration. They must use the return keyword to return a value of the specified type. They are useful when we need to process data and return a result.
  • Void methods: These methods use the void keyword to indicate that they will not return any value.

Reusing Static Methods within the Main class

  • We’ll start with a simple example. The idea is to create some lines of code that add two to a number. I’ll write the code and then analyze it step by step.
public class Main {

    public static void addTwo(int number) {
        int result = number + 2;
        System.out.println("The result of adding 2 to " + number + " is: " + result);
    }

    public static void main(String[] args) {
        addTwo(5);
    }

}

Let’s go with the explanation. Our method is highlighted in black. But first, we see the line that refers to the class we’re working in. As I mentioned in the first paragraphs of the topic, all methods must be within a class; otherwise, the program will return an error message. In this case, the Main class.

But on the other hand, it goes above the main method of the class:

public static void main(String[] args) {

}

Therefore, this class will have two methods, but only the code within the main method is executed. That’s why, if we want to use a secondary method, we must call it from the main method. In this example, we’ve created a secondary method, but there could be as many as needed.

Within the main method, public static void main(String[] args), we see how the addTwo method is being called:

addTwo(5);

We place the number to which we want to add two in parentheses. As we’ve created the method, it’s mandatory to enter a value in the parentheses, since we’ve specified it in the code by writing (int number). But we won’t always need to specify a value; that leads us to the next example.

  • Now we’re going to create the same example, but we want that when we call the method, it asks us for the number we want to enter via keyboard and then shows us what the sum of that figure plus two is.
import java.util.Scanner;

public class Main {

    public static void addTwo() {
        Scanner scanner = new Scanner(System.in);
        System.out.print("Enter a number: ");
        int number = scanner.nextInt();

        int result = number + 2;
        System.out.println("The result of adding 2 to " + number + " is: " + result);
    }

    public static void main(String[] args) {
        addTwo();
    }

}

Just like before, we write our method within the Main class and before the main method. In this case, we’ve created code that asks us to enter a number via keyboard and the program will add 2 to this value and also display the result on screen.

  • Now let’s imagine that, from time to time, we have to enter quite a long text in our code. We could write it every time, but the most elegant and orderly way is to create a method to reuse that text. We could do it as I show you below.
public class Main {

    public static void text() {
        System.out.println("Sometimes a text can be too long for us to be using it over and over again");
        System.out.println("It's better to create a method and then call it each time we need that text to be displayed.");
        System.out.println("Your program will be much cleaner and more organized");
    }

    public static void main(String[] args) {
        text();
    }

}

In the previous code, we’ve seen a method that basically consists of three lines of text. Whenever and wherever we need those lines to appear, we simply have to call our method and thus avoid having large texts mixed with the syntax.

  • As a final example (for now) we’re going to see a method in which we ask for two numbers and it returns their multiplication.
import java.util.Scanner;

public class Main {

    public static int product(int a, int b) {
        int c = a * b;
        System.out.println("The product of a * b = " + c);
        return c;
    }

    public static void main(String[] args) {
        product(4, 8);
    }

}

With these 4 examples we’ve seen 3 void functions and the last one that returns a value. That’s why when we created it we used static int instead of static void. Also, if you’ve noticed in the three void examples, in the first one we put a variable in parentheses: public static void addTwo(int number). In the other two we didn’t. This is because in the first one we wanted to write the figure manually ourselves. However, in the second one, the program didn’t need any data since it was going to start executing and ask us to enter data via keyboard. As for the text exercise, we didn’t have to specify any data either, the method always displays the same text.

Reusing methods created in classes other than the Main class

The first thing we’re going to do is create a class that we’ll call exercises. Initially it will look like this before we start writing our text:

public class Exercises {

// Here we'll write our methods.

}

Our Main class will be like this:

public class Main {

           public static void main(String[] args) {

                  // Here we'll call them.

           }

}

Now that we’ve created it, we’re going to go example by example writing the methods within it and then calling them from within the Main method of the Main class.

– In the first example we’re going to create a method in the Exercises class that tells us whether a number is even or not. We’ll enter the number manually when we call the method from the Main class.

This is the code of our method:

public class Exercises {

    public static boolean isEven(int number) {
        if (number % 2 == 0) {
            System.out.println("The number is even");
        } else {
            System.out.println("The number is odd");
        }

        // Returns true if the number is even, false if it's odd
        return number % 2 == 0;
    }

}

Up to here there’s no much loss, the exercise is simple. What you should pay attention to is which class it’s in and that within it we’ve created a public static boolean method. Now we must call it from the Main class.

For this we always follow a very simple structure. Within our Main class and within the main method we write the name of our class, then a dot and all of this followed by the method name and parentheses. If during the method declaration we haven’t used any variables in the parentheses, when we call the method from the main method, the parentheses will be empty. If during the declaration we use some variable, in the parentheses we’ll put the data we need. In this case it would be as follows:

Exercises.isEven(6);

The entire code of the Main method is as follows:

public class Main {

        public static void main(String[] args) {

                   Exercises.isEven(6);

        }

}

–      Now we’re going to do the same exercise, but in this case we have to enter the number via keyboard, then the program will tell us whether it’s even or not.

In the Exercises class is where we do all the work. This is how it would look:

import java.util.Scanner;

public class Exercises {

    public static void isEven() {
        Scanner exercise = new Scanner(System.in);

        System.out.println("Enter a number:");
        int number = exercise.nextInt();

        if (number % 2 == 0) {
            System.out.println("The number is even");
        } else {
            System.out.println("The number is odd");
        }
    }

}

We see that we import the Scanner in this class and not in the Main class. Otherwise it’s a very simple code.

To call the method from the Main class we’ll do it as follows:

public class Main {

          public static void main(String[] args) {

                  Exercises.isEven();

         }

}

–      To finish we use another void method of type String. The same one we used at the beginning of the topic.

The exercises class will be as follows:

public class Exercises {

    public static void text() {

        System.out.println("Sometimes a text can be too long for us to be using it over and over again");
        System.out.println("It's better to create a method and then call it each time we need that text to be displayed.");
        System.out.println("Your program will be much cleaner and more organized");

    }

}

And this will be the Main class:

public class Main {

      public static void main(String[] args) {

                  Exercises.text();

      }

}

Difference between class and instance

I want to explain to you what that static thing is that appears all the time in our methods, but for that you must first understand the difference between class and instance. A class, as we had already commented, is a mold or template that defines the properties (attributes) and behaviors (methods) common to all objects that will be created from it.

An instance is an object created from a class that has specific values for the attributes defined in the class.

Difference between static and dynamic methods

Static methods (All the ones we’ve been using so far) are directly associated with the class, not with specific objects of that class. This means they can be invoked without needing to create an instance (object) of the class.

For example:

public class Calculator {

       public static int add(int a, int b) { 

                    return a + b;

       }

}
// To use the add method, you don't need to create an object. We could call it from the Main class like this:

int result = Calculator.add(5, 10);

Dynamic methods belong to specific instances of a class. Each object created from a class has its own copy of the dynamic methods.

public class Car { 

    public void accelerate() {

         System.out.println("The car is accelerating.");

    }

}
// To use the accelerate method, you need to create an instance (object) Car myCar = new Car();

myCar.accelerate();

The concept of object is still somewhat unknown to you, but we’re going to remedy that. I know that after all this time programming linearly, the use of methods has changed your schemes a bit and now, on top of that, instances are piling up. But the truth is that it’s much easier than it seems. For the rest of the topic, we’re going to dive into it headfirst and soon you won’t have any doubts about it.

Working with instances or objects

What is an Object?

An object is a concrete entity that we can use in our programs. Imagine you have a blueprint to build a house. This blueprint would be the class, which describes what the house will be like, but the real house you build from the blueprint is the object. In programming, an object is an instance of a class and contains attributes (characteristics) and methods (actions).

Classes vs Objects

  • Class: It’s like a blueprint or recipe. It describes what characteristics and behaviors the objects created from it will have.
  • Object: It’s a concrete instance created from the class. It’s the real “thing” that we can use and manipulate in our program.

What is a Constructor in Java?

A constructor is a special type of method that is used to initialize objects. It’s the first method that is called when we create an object of a class. Its purpose is to give initial values to the object’s attributes. It is created within the class to which that object belongs. We’re going to see it much more clearly in the example I show you in the next point.

Basic Example of a Class and Object

  • We create the class: public class Person {
public class Person {

    String name;
    int age;

    // Constructor
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // Method to display the person's information
    public void displayInformation() {
        System.out.println("Name: " + name + ", Age: " + age);
    }

}
  • Now let’s go with the object
public class Main {

    public static void main(String[] args) {
        // Create an object of the Person class
        Person person1 = new Person("John", 25);

        // Use the object to call the displayInformation method
        person1.displayInformation();
    }

}

As you can see, in the person class we have two methods. The first is the constructor. Thanks to it, later in the Main class, we’ll be able to create objects and assign them values. The next method will simply display the values on screen. It uses the information provided by the constructor method.

Definition of Getter Methods

Purpose: A getter method is used to obtain the value of a private attribute of a class. It’s a safe way to access data without allowing it to be modified directly.

public class Person { 

private String name;

         // Getter method for the name attribute 

        public String getName() {

                 return name;

         }

}

Definition of Setter Methods

Purpose: A setter method is used to set or modify the value of a private attribute of a class. It allows controlling how the value is changed and can include validations.

Syntax:

public class Person { 

        private String name;

        // Setter method for the name attribute

        public void setName(String name) { 

                     this.name = name;

        }

}

Example of Getters and Setters

Let’s see a complete example with a Person class that has an age attribute and uses getter and setter methods to handle it.

public class Person {
    
    private int age;

    // Getter method for the age attribute
    public int getAge() {
        return age;
    }

    // Setter method for the age attribute
    public void setAge(int age) {
        if (age > 0) {
            this.age = age;
        }
    }

}
public class Main {

    public static void main(String[] args) {

        Person person1 = new Person();

        // Set the age using the setter
        person1.setAge(25);

        // Get the age using the getter
        System.out.println("Age: " + person1.getAge());
    }

}

Did you like it? Don’t keep it to yourself — share it like juicy gossip! 😏