OOP_1-#part2|Java OOP Concepts: ‘this’ and ‘final’ Keywords, Constructors, Inheritance, and Super Class Constructors.

Nikita pandey
7 min readFeb 18, 2023

Sharing my notes here because why not?

1. The ‘this’ Keyword

  • this can be used inside any method to refer to the current object, i.e., the object on which the method was invoked.
  • It is useful when a method needs to refer to the object that invoked it.
  • Here’s an example:
class Person {
String name;

public Person(String name) {
this.name = name;
}

public void sayHello() {
System.out.println("Hello, my name is " + this.name);
}
}

Person p = new Person("Alice");
p.sayHello(); // Output: Hello, my name is Alice

2. The "final” Keyword

  • A field can be declared as final, making it essentially a constant.
  • It prevents the field’s contents from being modified after initialization.
  • It is a common coding convention to choose all uppercase identifiers for final fields.
  • If an instance variable of a reference type has the final modifier, the value of that instance variable (the reference to an object) will never change, but the value of the object itself can change.
  • Here’s an example:
class Circle {
final double PI = 3.14159;
final int radius;

public Circle(int r) {
this.radius = r;
}

public double getArea() {
return PI * radius * radius;
}
}

Circle c = new Circle(5);
System.out.println(c.getArea()); // Output: 78.53975

Question->>

What do we mean by “If an instance variable of a reference type has the final modifier, the value of that instance variable (the reference to an object) will never change, but the value of the object itself can change.”?

When an instance variable of a reference type is marked as final, it means that the variable’s reference cannot be changed to point to a different object after it has been initialized. However, it does not prevent the object itself from being modified.

For example, let’s say we have a class called Person with a final instance variable called name, which is of type String. We can initialize this variable in the constructor, and once it is initialized, we cannot change the reference to the String object that it points to. However, we can still modify the contents of the String object itself.

Here’s an example:

public class Person {
private final String name;

public Person(String name) {
this.name = name; // Initialize the name variable with the input argument
}

public void setName(String newName) {
// This line will not compile, because we can't change the reference of a final variable
// this.name = newName;

// However, we can still modify the contents of the String object that the name variable points to
this.name = this.name.toUpperCase();
}

public String getName() {
return this.name;
}
}

In the setName method, we cannot change the reference of the final name variable to point to a different String object, because it is marked as final. If we try to do this, the code will not compile. However, we can still modify the contents of the String object that the name variable points to. In this case, we are converting it to all uppercase using the toUpperCase method.

So in summary, marking an instance variable of a reference type as final means that the variable’s reference cannot be changed, but the contents of the object itself can still be modified.

Photo by Markus Spiske on Unsplash

3. The finalize() Method

  • The finalize() method is used to define specific actions that will occur when an object is just about to be reclaimed by the garbage collector.
  • To add a finalizer to a class, you simply define the finalize() method.
  • The Java runtime calls that method whenever it is about to recycle an object of that class.
  • Here’s an example:
class Box {
protected void finalize() {
System.out.println("Box object is being garbage collected");
}
}

Box b = new Box();
b = null; // b is no longer referencing the Box object, so it will be garbage collected

4. Constructors

  • A constructor is a special method that is called when an object is created.
  • It has no return type, not even void.
  • The implicit return type of a class’ constructor is the class type itself.
  • Constructors are automatically called when the object is created before the new operator completes it.
  • Here’s an example:
class Car {
String make;
String model;
int year;

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

Car c = new Car("Toyota", "Camry", 2022);

Questions->>

How can we say that the implicit return type of a class’ constructor is the class type itself?

In Java, constructors are special methods that are used to create and initialize objects. They have the same name as the class and no return type, not even void. This is because the return type of a constructor is implicitly the class type itself.

For example, let’s say we have a class called Person with a constructor that takes in a String the argument for the person's name:

public class Person {
private String name;

public Person(String name) {
this.name = name;
}
}

In this example, the constructor has the same name as the class (Person) and it takes in a String argument for the person's name. Notice that the constructor does not have a return type. This is because the implicit return type of the constructor is Person, which is the class type itself.

When we create a Person object using the new keyword, the constructor is automatically called and returns an instance of the Person class. For example:

Person person = new Person("John");

In this example, we create a Person object named person and pass in the argument "John" to the constructor. The constructor initializes the name instance variable with the value "John", and then returns an instance of the Person class.

What you can understand from this line “Constructors are automatically called when the object is created before the new operator completes it.”

When you create a new object using the new keyword, memory is allocated for the object and then its constructor is called automatically to initialize the object. The new operator allocates memory for the object and then calls the constructor to perform the initialization. The constructor must complete its execution before the new operator completes its execution and returns the reference to the newly created object. This means that by the time the new operator completes, the object has already been fully initialized by the constructor.

5. Inheritance and Constructors in Java

  • A constructor of the base class with no arguments gets automatically called in the derived class constructor.

In Java, if a constructor of a derived class is invoked, then the constructor of its parent (base) class with no arguments is automatically called before the derived class constructor executes. This happens even if you do not explicitly call the base class constructor using the super() keyword in the derived class constructor.

This is because every class has a constructor, even if it is not explicitly defined. If a class does not define a constructor, the Java compiler automatically generates a default constructor with no arguments. This constructor calls the constructor of its parent (base) class with no arguments using the super() keyword.

For example, suppose we have a class Person with a constructor that takes no arguments. Then, we create a derived class Employee that extends Person and defines its own constructor. If we create an instance of Employee using the new keyword, the constructor of Person with no arguments will automatically be called before the constructor of Employee is executed.

Here’s an example code snippet that demonstrates this behavior:

class Person {
public Person() {
System.out.println("Person constructor called");
}
}

class Employee extends Person {
public Employee() {
System.out.println("Employee constructor called");
}
}

public class Main {
public static void main(String[] args) {
Employee emp = new Employee();
}
}

When we run this program, we will see the following output:

Person constructor called
Employee constructor called

As we can see, the constructor of Person is automatically called when we create an instance of Employee, even though we did not explicitly call it using the super() keyword in the constructor of “Employee”

  • If the derived class does not have a default constructor, the JVM will invoke its default constructor and call the super class constructor by default.
  • If the super class does not have a default constructor but has a parameterized constructor, the derived class constructor should explicitly call the parameterized super class constructor.
  • Here’s an example:
class Animal {
public Animal() {
System.out.println("Animal constructor called");
}
}

class Dog extends Animal {
public Dog() {
System.out.println("Dog constructor called");

Question->>

Explain-“If the super class does not have a default constructor but has a parameterized constructor, the derived class constructor should explicitly call the parameterized super class constructor.”

Yes, that’s correct. When a subclass is created, its constructor always calls its superclass constructor first. If the superclass has a default (no-arg) constructor, it is called automatically. However, if the superclass does not have a default constructor and only has a parameterized constructor, then the subclass constructor must explicitly call the superclass constructor with the appropriate arguments using the super() keyword.

Here is an example to illustrate this:

class Person {
private String name;
private int age;

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

class Student extends Person {
private int studentId;

public Student(String name, int age, int studentId) {
super(name, age); // calling the superclass constructor with arguments
this.studentId = studentId;
}
}

In this example, Person has a constructor that takes two arguments, name and age. When a Student object is created, the Student constructor calls the Person constructor using the super() keyword with the name and age arguments.

Summary: Notes on Java Programming Concepts and Examples. Includes topics such as “this” keyword, “final” keyword, constructors, and inheritance. Provides code examples to illustrate each concept.

--

--

Nikita pandey

Python developer| Data science student| detective by nature| into art,AI, and books