Classes and Objects

 

A Java class is a blueprint for initializing new objects. It serves as a container for the description of the properties and behaviors of the objects that are initialized from it. An object is a specific an instance of a class. All the instances of a class share the same properties and behavior defined in the class. Each instance has its own state defined by the values of its properties.

Java Class Declaration

A Java class is declared at the bare minimum

class <class name> {

<class body>

}

The class name follows Java naming conventions. Everything that the class defines, like methods, instance variables go into the class body.

Depending on the use, the class declaration can have the following additional components:

1- If the class implements interfaces, implements keyword along with the interfaces implemented. If there’s more than one interface implemented, the interface names are separated by commas.

class MainClass implements MyInterface, SecondInterface {

2- If the class extends another class, the extends keyword and the class being extended

class MainClass extends SuperClass {

3- An access modifier preceding the class keyword

public class MainClass {

4- If the class is abstract, abstract keyword preceding the class keyword

abstract class AbstractClass {

Every Java application needs to have a main method with the following signature

public static void main(String [] args) method

The class that contains a main method needs to be declared public. In addition, the .java file that contains the class code should have the same name as the class. For example, if the class that contains the main method is named MyClass, it should be declared as

public class MyClass …

and the java file that contains the class code should be named MyClass.java. Only then, the code in the main method of the class can be run by the JVM using the java command.

For example, let’s say we want to have a Person blueprint to initialize new Person objects based on some specific properties and behaviors. A Person may have

  • a first name
  • a last name
  • age

as common properties and a Person

  • says his/her fullName
  • says how old he/she is

as common behaviors. Because all people possess these properties and behaviors, the blueprint Person class may define all of them.

Now that we have the template, Person objects can be initialized from Person class template with their properties and behaviors as in

  • James, West, 48, says says his full name, says his age
  • Miranda, Wellington, 39, says her full name, says her age

Now, let’s put this to code and create the Person blueprint as a class.

public class Person

{

public String firstName;

public String lastName;

public int age;

public void sayName(){

System.out.println(“My name is + firstName + “ “ + lastName);

}

public void sayAge(){

System.out.println(“I am “ + age + “ years old.”);

}

}

Fields of a Java class

Properties of a class are defined inside the class’ body, out of any method of the class and they are called instance variables, member variables or fields of the class. Once an object is initialized from the class, instance variables determine the state of the object with their values.

A member variable of a class is declared as

<access modifier> <variable type> <variable name>;

Optionally, instance variables can be initialized at the class level with the format

<access modifier> <variable type> <variable name> = <value>;

For example;

public int x = 5;

It is important to give meaningful names to all the variables in a Java program. For example, if we plan to keep the first name of a person in a member variable, it would not make sense to call it firstName. Member variable names follow Java naming conventions which we will talk about in a later chapter.

The Person class we defined has three instance variables: firstName, lastName, age.

Methods of a class

Methods of a class are defined inside the body of the class and they follow method declaration conventions. A method is defined as follows:

<access modifier> <return type> <methodName>(<arguments>) {

<method body>

}

The methods of a class determine the behavior of objects initialized from it.

Person class has 2 methods that define the behavior of Person instances: sayName and sayAge.

Java Objects

A Java object is an instance of a Java class that has its own state and behavior. Java classes are used as blueprints to initialize Java objects.

A Java object is initialized from its blueprint with the new keyword. Creating a Java object from its blueprint and assigning it to an object variable of the object’s type is typically as follows:

<class name> <variable name> = new <class name>();

The creation of an object from a class happens in 3 steps:

1- declaration: The right hand side of the = operator is called the declaration. Here, a Java object of the class type <class name> is declared but it yet points to nothing.

2- instantiation: new keyword allocates the memory for a new object of type <class name> in JVM. This process is called instantiation. Yet, the memory is just allocated and does not hold anything.

3- initialization: Following declaration and instantiation, <class name>() part of the statement calls the class’ constructor method, creates the object and the object is held in the memory that was allocated during instantiation. This process is called initialization. Following that, with the = operator, the new object is assigned to the declared variable.

For example, a new Person object is created from a Person class as follows.

Person person = new Person();

Once this statement is executed, we have a variable named person, of class type Person, and it points to the location in memory that was allocated to hold the Person object.

Accessing the methods and instance variables of an object

An object’s methods and instance variables are accessed using the . (dot) operator. The format for accessing methods and instance variables are as follows.

For instance variables,

<object name>.<instance variable name>

For methods,

<object name>.<method>

A class has access to all the variables and methods that it defines. Whether the methods and fields of an object defined inside a class are visible to a different class are determined by access modifiers of those methods and variables. We will discuss class access in the next chapter.

Now, let’s create a Person object from a Person class and see the method calls in action.

public class Person

{

public String firstName;

public String lastName;

public int age;

public void sayName(){

System.out.println(“My name is + firstName + “ “ + lastName);

}

public void sayAge(){

System.out.println(“I am “ + age + “ years old.”);

}

public static void main(String [] args) {

1 Person p = new Person();

2 p.firstName = “James”;

3 p.lastName = “West”;

4 p.age = 48;

5

6 p.sayName();

7 p.sayAge();

8 System.out.println(p.firstName + “ “ + p.lastName + “ is “ + p.age + “ years old”);

}

}

Once compiled and executed, the Person class will generate the output

My name is James West

I am 48 years old

James West is 48 years old

Inside the main method of the Person class, first a Person object is declared on line #1.

Person p

Following this, an instance of the Person class, in other words a Person object, is assigned to this

Person p = new Person();

Now, p is an object variable of type Person. It has a firstName, lastName and age, and it can sayName and sayAge. However, yet it is only initialized, none of its properties is set and therefore, they cannot yet be used. First we need to set these properties so that they can be used later in the program.

We follow the following pattern while setting the properties of object p, using the . operator.

<object name>.<property name> = <property value>

Line #2 sets the first name of the person.

p.firstName = “James”;

Line #3 sets the last name of the person.

p.lastName = “West”;

Line #4 sets the age of the person.

p.age = 48;

Now, p is a person whose first name is James, whose last name is West and p is 48 years old.

Starting from line #6, calls are made to the methods defined in the Java class that contain the behavior of a Person. We use the following format to call an object’s methods, using the . operator.

<object name>.<method name>(arguments);

Line #6 calls sayName() method of Person object p, which prints the full name of the person.

Line #7 calls sayAge() method of Person object p, which prints the age of the person.

Line #8 makes a string by appending “ “ to the value of firstName, then appends to this lastName, another “ “, value of ageOfPerson and “ years old”. The result is “James West is 48 years old” and it is printed out on the console.

What is a class constructor method?

Constructors are methods that are invoked when an object is created from the class that they belong to. Initial work before an object is created is performed inside the constructor method. A constructor method doesn’t have a return type and its method name is the same as the class’ name that it belongs to.

A class constructor is defined as follows:

<access modifier> <class name>(<arguments>) {

<constructor method body>

}

Every Java class that is defined without a constructor method has a default constructor that has no arguments. If the class defines other constructor methods, the default no-argument constructor is no longer available within the class and the class can be initialized using only the new constructors. If the access modifier is private, the class cannot be initialized by other classes. If it is protected or does not have an access modifier (default access), only classes in the same package can initialize the class.

Java allows overriding the the default, public, no-arg constructor.

public class MyClass {

public MyClass() {

System.out.println(“This is the overridden public constructor with no arguments.”);

}

}

The class in this example has a public, no-arg constructor that overrides the implicit one provided by the JVM.

It is also possible to pass information to a constructor method by using constructor arguments. In this case, the constructor method has access to the values passed for the arguments and can use them in its initial work for the class.

public class Employee {

private String firstName;

private String lastName;

public Employee(String firstName, String lastName) {

this.firstName = firstName;

this.lastName = lastName;

}

}

Here, Employee object has two private fields that are not visible to outside. However, using the constructor, they can be set when the object is initialized. The Employee object has no other constructor so this guarantees that firstName and lastName properties are set when a Employee object is created.

What is this keyword?

this is a keyword in Java that is used within an object method or constructor as a reference for the object. For example, while inside a constructor method of a class, if one of the instance variables of the same class is accessed, this is done through this as there’s no instance of the class yet inside the method. When one of the class’ instance variables or methods is accessed inside the class itself, it, by default, belongs to this.

In this example, this keyword is used as a reference to the object that is being created. In a broader context, inside a class’ methods, this keyword is used to refer to the object that will be created from the class. In this example, when the constructor is called, there’s no object yet. The statement

this.firstName = firstName

translates to “While creating a class from this object, set its firstName property to firstName argument that is passed to this constructor method.”. We will talk about this keyword in more detail later.

A class can have multiple constructors with different signatures. Constructor methods also can call other constructor methods.

Now, let’s go back to the Person class we defined before. The Person class has no constructors defined in the code. That means it has a public, no-arg constructor. When we initialize a Person object, this public, no-arg constructor is called.

Now, let’s override the public no-arg constructor and add another constructor to the Person class that initializes the fields with the values passed.

public class Person

{

private String firstName;

private String lastName;

private int age;

public Person() {

System.out.println(“This is a person object.”);

}

public Person(String constFirstName, String constLastName, int constAge) {

this.firstName = constFirstName;

this.lastName = constLastName;

this.age = constAge;

System.out.println(“Initializing the Person object with arguments.);

}

public void sayName(){

System.out.println(“My name is + firstName + “ “ + lastName);

}

public void sayAge(){

System.out.println(“I am “ + age + “ years old.”);

}

public static void main(String [] args) {

Person firstPerson = new Person();

Person secondPerson = new Person(“James”, “West”, 48);

p.firstName = “James”;

p.lastName = “West”;

p.age = 48;

firstPerson.sayName();

firstPerson.sayAge();

System.out.println(firstPerson.firstName + “ “ + firstPerson.lastName + “ is “ + firstPerson.age + “ years old”);

secondPerson.sayName();

secondPerson.sayAge();

System.out.println(secondPerson.firstName + “ “ + secondPerson.lastName + “ is “ + secondPerson.age + “ years old.”);

}

}

If we run this program, we get the following output.

This is a person object.

Initializing the Person object with arguments.

My name is James West

I am 48 years old

James West is 48 years old

My name is Miranda Wellington

I am 39 years old

Miranda Wellington is 48 years old

Person class has two constructors. The first one is the overridden version of the default constructor and is called whenever a Person object is initialized with no arguments. The second constructor has three arguments that are used to pass information while initializing a Person object.

In the main method, we create two Person objects. The first one is created with the overridden no argument constructor. Thus, while creating this object, the no-argument constructor is called in the initialization phase and “This is a person object” is printed on the console. By the time the firstPerson object is ready, none of the fields is set a value and they all have their default values.

The second object is initialized using the second constructor which has 3 arguments. When secondPerson is created, this second constructor is called and inside the constructor, the fields are initialized with the values passed as arguments. While creating the object, firstName field of the secondPerson object is set to “James”, lastName field is set to “West” and age field to 48. After this, “Initializing the Person object with arguments.” is printed on the console.

After initializing both of the objects, using the new values of secondPerson object’s fields, the sentence

James West is 48 years old.” is printed on the console. By the time the System.out.println call is made, the initial work for the secondPerson object is already done and the fields have their new values.

While calling a constructor method that has arguments, the arguments that are passed need to match the declared types. Doing otherwise causes a compilation error.

What is an immutable object?

An immutable object cannot be changed once it is declared and initialized. This is mostly achieved by making the fields of the class not accessible to other classes. For example, let’s take a look at the following class.

public class ImmutableClass {

private final int i;

public ImmutableClass(int I) {

this.i = I;

}

public int getI() {

return I;

}

}

Once this class is initialized, the value for the instance variable is set. Because the instance variable is final, the value that was set cannot be changed later. So, the state of an object initialized from this class cannot be changed following initialization, making the object immutable.

We also need to note that, a reference variable pointing to an immutable object can be set to point to a new instance of the immutable object’s class. For example, the following would be legal.

ImmutableClass immutableClass = new ImmutableClass(1);

immutableClass = new ImmutableClass(2);

Here, on the second line, the immutableClass variable is assigned a new object. The object that was initialized on the first line is not changed.

Class loading and Class Initialization

A Java Program’s execution always starts with the main function. It is also possible to execute code before the main method in the Java language using static blocks. Once the program flow is inside the main method, each statement is executed sequentially.

A Java class needs to be loaded into the JVM first before it can be initialized. Class loading refers to the process of loading the byte code of the compiled class into the JVM. Class loading is done by the java.lang.ClassLoader class. Class loading also happens when a static method or a static variable belonging to that class is accessed by the program flow. Class loading initializes all static variables of a class.

Class initialization may happen only after the class loading takes place. A class is initialized when

1- an object is created from the class using the new keyword or using reflection

2- a static method of a class is called, a static field of a class is set or a static field of a class that is not declared final is used. A final field’s value cannot be changed once it is set.

These items are to be deleted

1) an Instance of class is created using either new() keyword or using reflection using class.forName(), which may throw ClassNotFoundException in Java.

2) an static method of Class is invoked.

3) an static field of Class is assigned.

4) an static field of class is used which is not a constant variable.

5) if Class is a top level class and an assert statement lexically nested within class is executed.


What is a code block?

A code block is a group of statements brought together and surrounded by curly braces, starting with { and }. It is a logical unit of code that works as a single piece. Java uses code blocks with many of its components. For example, every Java method’s body is a code block. Code blocks can have nested code blocks inside them. A variable defined in a code block is accessible only inside that block.

What is a static initialization block?

A static initialization block is a block of code that is preceded by the static keyword. Static code blocks do not belong to a specific instance of the class. When a class is loaded by the JVM, static code blocks are executed first, with the order they are defined in the class, before any constructor runs.

public Rectangle {

private int width;

private int height;

static {

System.out.println(“Inside the static block.”);

}

public Rectangle(int width, int height) {

System.out.println(“Inside the constructor”);

this.width = width;

this.height = height;

}

public static void main(String [] args) {

Rectangle rectangle = new Rectangle(3, 5);

System.out.println(“width: “ + rectangle.width + “ “ + “, height: “ + rectangle.height + “, area:“ + rectangle.width * rectangle.height);

}

}

When this program is compiled an run, it first gets loaded into the JVM. Therefore, static code block gets executed first. Following that, the main method initializes a Rectangle object, calling the constructor. The output is

Inside the static block.

Inside the constructor

width:3 height: 5 area: 15

%d bloggers like this: