• 15 hours
  • Easy

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 3/28/24

Take a closer look into methods: defining instance methods & fields

What is a method?

You already know a little about functions, which are blocks of code with a name, that you can reuse. That block of code is a set of instructions you want a program to perform.

But what are methods?

Methods are also functions defined inside a class. Since everything in Java is defined inside a class, every function is also a method. You can, however, isolate instance methods, that are executed within the context of an object from class methods, which operate directly on the class.

That sounds a bit abstract, so let’s break it down.

Defining instance methods

When you define a class, you define its fields in the form of variables. Then you can write methods to work with those fields.

For example, let's define a class with two integer numbers:

class MagicMath {
    int a;
    int b;
}

Then you can create a method within the class that will change those values:

class MagicMath {
    int a;
    int b;

    public static void changeValues() {
        a = 2;
        b = 7;
    }
}

Since this method is working with the values of fields that only exist once an object is created, it's called an instance method.

To be able to use an object of this class, you need to instantiate it - bring into being by creating a variable of this class:

MagicMath magicMath = new MagicMath();

After that you can call your new method to change values of the new instance of the class:

magicMath.changeValues();

As you noticed above, to call a method you use a dot notation which is common in many programming languages. It means you need to write the name of an instance variable followed by the method name, separated by a dot: instanceVariableName.methodName();.

Back to our example, let's bring all the code together:

package methods;

class MagicMath {
    int a;
    int b;

    public static void changeValues() {
        this.a = 2;
        this.b = 7;
    }

    public static void main(String args[])
    {
        MagicMath magicMath = new MagicMath();
        System.out.println("a=" + a ", b=" +b);
        magicMath.changeValues();
        System.out.println("a=" + a ", b=" +b);
    }
}

Let's compile and run this code:

$ javac methods.MagicMath.java
$ java methods.MagicMath
a=0, b=0
a=2, b=7

Notice how we were able to print the content of the attributes before assigning a value? Contrary to what happens with local variables, Java initializes fields automatically with the default value for the type of the field if no value is provided.

If you want the object to be created with a different value than the default value for each field, you need to write a special method called a constructor. A constructor is a method that is called automatically when the object is instantiated. It can set the values for the fields directly or through another method.

Here is an example with a constructor that uses a method to set the initial values:

class MagicMath {
int a;
int b;

/** Creates the object through the changeValues() method */
public MagicMath(){
    this.changeValues();
}

/** sets a value of 1 for a and a value of 5 to b */
public void changeValues() {
    this.a = 1;
    this.b = 5;
}

Any object instantiated from this class will be  initialized with the values defined in the  changeValues method.

Defining class members

You now know that you can create methods that can work with the value of the fields of instances of a class. There is another group of methods that you can create which apply to the class in general. These are called class methods and do not require the instantiation of an object. They are used to work with class attributes or perform some instructions that relate to the class in general.

In Java, class members (fields and methods) are marked with the static keywords at the declaration. Here is an example of a class method and a class attribute inside a class definition:

class ClassName {
    double instanceVariable;
    static int classVariable;

    public void instanceMethod() { 
    // can access both the instanceVariable and the classVariable
    }

    public static void classMethod() { 
    // only works at the class level, can only access classVariable
    }
}

To call class methods, you use the same dot notation as for instance methods. However, the call is made directly on the class name.

ClassName.classMethod()

For example, you can declare a class Car with a static field that will be incremented each time you create an instance of the class. That way you will keep track of the number of Car objects that have been created.

class Car {
    static int count = 0;

    static void increment() {
        Car.count += 1;
    }
}

Every time you produce a Car object, you can increase the count:

Car.increment()

It's important to know the difference between the two categories of methods and make the appropriate decision for the implementation of your classes.

Let's reiterate:

  • Instance methods work in the context of an instance of a class. They require object instantiation.

  • Class methods operate in the context of a class in general and do not require object instantiation.

Class methods are used in particular inside support classes that provide functionalities that can be used by several classes. The Math class is a good example of a support class.

On the other hand, blueprint classes are the most valuable because they define both a state (with fields) and a behavior (with instance methods). You have already seen that you can make sure an instance is created with the proper values thanks to a constructor. Let's now see how we can make sure the values remain relevant for your needs.

Control field values with getters and setters

When working with classes and objects, you must make sure the object remains valid for its purpose from the time of creation until it is no longer used.

For this, three special methods are used:

  1. Constructors- which ensure that proper values are given to the fields of the object as soon as it is created.

  2. Accessors- whose only purpose is to return the current value of a field. This means that you can mark your fields as private and only provide accessors for the ones that should be accessed by other classes.

  3. Mutators- which not only control which fields can be modified, but can also enforce business rules on which values can be set.

To be able to use an accessor, you need to explicitly declare a method. By convention:

  • An accessor for a field is named by the string get  , followed by the name of the field.

  • A mutator will be named set , followed by the name of the field.

For example, let's declare a Square class with two attributes: length and width. Here's what it looks like in Java:

public class Square {
    private int length;
    private int width;
    
    public Square(int length, int width){
        this.length=length;
        this.width=width;
    }

    public int getLength(){
        return this.length;
    }

    public void setLength(int length) {
        this.length = length;
    }
}

And then we can use it:

public static void main(String[] args){
    // create a square with a length of 10 and a width of 4
    Square square = new Square(10,4);

    System.out.println(square.length); // does not work: length is private
    System.out.println(square.getLength()); // -> 10

    square.setLength(16);
    System.out.println(square.getLength(); // -> 16
}

If you are interested in an additional attribute that you can infer from existing fields (such as the perimeter), you can define an additional method that will make use of the fields. This method will not use the accessors or mutators syntax.  

Summary

In this chapter, you've learned:

  • Methods of a class are functions that operate in the context of that class.

  • Instance methods operate on fields of the instance of that class. Instance methods call on an object after it's been instantiated.

  • Class methods operate in the global context of a class and don't require instantiation of an object.

  • To call methods, a dot notation is commonly used: instanceVariableName.methodName orClassName.methodName.

  • Constructors, accessors, and mutators are special methods that ensure the validity of the values of the fields of an object. 

Example of certificate of achievement
Example of certificate of achievement