Search Logic Blocks

Wednesday, August 19, 2020

Java: How to access superclass constructors

As we have already discussed about inheritance earlier and we have also learnt about how to override the superclass methods in subclasses. Superclass is a common class, subclass can access all non-private members from the superclass and can also add new own members. Superclass non-private member variables can be accessed directly, but superclass constructors and non-private member methods can be accessed by using a keyword super. 

How to access Superclass constructor
If the subclass doesn't have any constructor and superclass has a constructor with no arguments, by default the superclass constructor method is invoked. Let's take the example Shape, Triangle and ShapesTest from earlier post and modify by adding two constructor methods -
public class Shape {
final static double PI = Math.PI;
double width = 0;
double height = 0;

// Superclass constructors
Shape() {
this.width = 5;
this.height = 8;
}

Shape(int width, int height) {
this.width = width;
this.height = height;
}

// Returns the text telling what shape it is
public String whatShape() {
return "";
}

// Returns the area of the shape
public double area() {
return 0.0;
}
}
public class Triangle extends Shape {
// Returns the text telling what shape it is
public String whatShape() {
return "Triangle";
}

// Returns the area of the shape - can access parent's declared variables
public double area() {
return Math.round((height * width / 2) * 100) / 100.0;
}
}
public class ShapesTest {
public static void main(String args[]) {
// Created a triangle shape
Triangle triangle = new Triangle();

System.out.println(triangle.whatShape());
System.out.println(triangle.width);
System.out.println(triangle.height);
}
}
In the above example, Shape class has two constructors and Triangle class doesn't have any constructor. But when an instance of Triangle class is created, superclass constructor is automatically called. Here is the output for above code -

Triangle
5.0
8.0

Let's add one new member variable and one constructor in subclass Triangle with no arguments. And also print the new member variable value in the ShapesTest class. We have added new member variable as fillColor and Triangle class constructor initializes fillColor as "Red" -
public class Triangle extends Shape {
String fillColor;
// Triangle Constructor with no arguments
Triangle() {
this.fillColor = "Red";
}
// Returns the text telling what shape it is
public String whatShape() {
return "Triangle";
}

// Returns the area of the shape - can access parent's declared variables
public double area() {
return Math.round((height * width / 2) * 100) / 100.0;
}
}
public class ShapesTest {
public static void main(String args[]) {
// Created a triangle shape
Triangle triangle = new Triangle();

System.out.println(triangle.whatShape());
System.out.println(triangle.width);
System.out.println(triangle.height);
System.out.println(triangle.fillColor);
}
}
In the above example, we have added one new member variable fillColor in subclass Triangle. When the new instance of Triangle class is created, superclass constructor is called automatically following by the subclass constructor with no arguments. Here is the output of above code -

Triangle
5.0
8.0
Red

Let's create another constructor in subclass with one argument to set value of the subclass member variable fillColor dynamically. Still, the superclass constructor (with no arguments) is called implicitly before calling the subclass constructor, and superclass member variables are initialized. Here is the code -
public class Triangle extends Shape {
String fillColor;
// Triangle Constructor with no arguments
Triangle() {
this.fillColor = "Red";
}

// Triangle Constructor with one argument
Triangle(String fillColor) {
this.fillColor = fillColor;
}
// Returns the text telling what shape it is
public String whatShape() {
return "Triangle";
}

// Returns the area of the shape - can access parent's declared variables
public double area() {
return Math.round((height * width / 2) * 100) / 100.0;
}
}
public class ShapesTest {
public static void main(String args[]) {
// Created a triangle shape
Triangle triangle1 = new Triangle();

Triangle triangle2 = new Triangle("Blue");

System.out.println(triangle1.whatShape());
System.out.println(triangle1.width);
System.out.println(triangle1.height);
System.out.println(triangle1.fillColor);

System.out.println();
System.out.println(triangle2.whatShape());
System.out.println(triangle2.width);
System.out.println(triangle2.height);
System.out.println(triangle2.fillColor);
}
}
And the output is -

Triangle
5.0
8.0
Red

Triangle
5.0
8.0
Blue

But, if you are not sure if the superclass constructor is called, you can call it by using super() method. It will give the same result as above. Here is the code with subclass constructor with call to superclass constructor using super() method (note that superclass constructor call statement should be the first statement in the subclass constructor) -
public class Triangle extends Shape {
String fillColor;
// Triangle Constructor with no arguments
Triangle() {
super();
this.fillColor = "Red";
}

// Triangle Constructor with one argument
Triangle(String fillColor) {
this.fillColor = fillColor;
}
// Returns the text telling what shape it is
public String whatShape() {
return "Triangle";
}

// Returns the area of the shape - can access parent's declared variables
public double area() {
return Math.round((height * width / 2) * 100) / 100.0;
}
}
Only subclass Triangle is changed, and the output is same above -

Triangle
5.0
8.0
Red

Triangle
5.0
8.0
Blue

Let's add one more constructor in subclass which takes three arguments and calls superclass constructor method with two arguments. Here we will use again super() method but with two arguments. Here is the code - 
public class Triangle extends Shape {
String fillColor;
// Triangle Constructor with no arguments
Triangle() {
super();
this.fillColor = "Red";
}

// Triangle Constructor with one argument
Triangle(String fillColor) {
super();
this.fillColor = fillColor;
}

// Triangle Constructor with three arguments
Triangle(double width, double height, String fillColor) {
super(width, height);
this.fillColor = fillColor;
}

// Returns the text telling what shape it is
public String whatShape() {
return "Triangle";
}

// Returns the area of the shape - can access parent's declared variables
public double area() {
return Math.round((height * width / 2) * 100) / 100.0;
}
}
public class ShapesTest {
public static void main(String args[]) {
// Created a triangle shape
Triangle triangle1 = new Triangle();

Triangle triangle2 = new Triangle("Blue");

Triangle triangle3 = new Triangle(4, 6, "Purple");

System.out.println(triangle1.whatShape());
System.out.println(triangle1.width);
System.out.println(triangle1.height);
System.out.println(triangle1.fillColor);

System.out.println();
System.out.println(triangle2.whatShape());
System.out.println(triangle2.width);
System.out.println(triangle2.height);
System.out.println(triangle2.fillColor);

System.out.println();
System.out.println(triangle3.whatShape());
System.out.println(triangle3.width);
System.out.println(triangle3.height);
System.out.println(triangle3.fillColor);
}
}
Here is the output of above example -

Triangle
5.0
8.0
Red

Triangle
5.0
8.0
Blue

Triangle
4.0
6.0
Purple

Note that the super() method call is the first statement in subclass constructors. You can find code at Github Link.

Friday, August 14, 2020

Java: Static Initialization Block

What is a Block?

So far, we have written so many programs and in every program we have different kinds of blocks - class block, method block, loop block etc. Any code between opening parentheses and closing parentheses is called a block. And the variables declared in the block can not be accessed outside from the block. For ex:

class [class name] {

}

for(.....) {

}

We can have a block without any name like below :

{
    int x = 5;
}

And the variable x is not accessible outside from the block. Here is the example code -
public class Block {
public static void main(String args[]) {
int x = 10;
String str = "Block Example";
System.out.println("Value of x is : " + x);
System.out.println("This is : " + str);
{
int y = x + 5;
System.out.println("This is inside the block");
}
// System.out.println("Value of y is : " + y);
}
}
In the above code, commented code shows that the variable is declared in the block, so it can not be accessed outside from the block. Here is the output of above code -

Value of x is : 10
This is : Block Example
This is inside the block

What is an Initialization Block?

Initialization block, is the block of code used when initializing the class variables at the start of the class declaration. Mostly initialization block is used to assign the default values to class variables. The initialization block can have any valid Java statement. Here is the example of initialization block -
public class InitBlock {
int x;
int y;
static int z;

{
System.out.println("Initialization Block");
x = 10;
y = 15 + x;
z = 20;
System.out.println("Value of x is: " + x);
System.out.println("Value of y is: " + y);
}
}
public class InitBlockDemo {
public static void main(String args[]) {
InitBlock ib = new InitBlock();
System.out.println("value of z is: " + InitBlock.z);
}
}
In the above example, initialization block has the print statement. When the instance is created, the statements in initialization block are executed. Here is the output -

Initialization Block
Value of x is: 10
Value of y is: 25
value of z is: 20

What is Static Initialization Block?

We have already discussed about Static Variables, Static Methods, Static Inner Classes. We already know, that to access the static variables, methods and inner classes, there is no need to create the instance of the class. They can be accessed directly through class itself. And, we also know that the static methods and the static inner classes can access only the other static members of enclosing class, not non-static members.

Static initialization block is the initialization block which is used to initialize only the static class variables. It can not access non-static variables. Here is the conversion of above example into static initialization block example.
public class StaticInitBlock {
int x;
int y;
static int z;

static {
System.out.println("Static Initialization Block");
// x = 10;
// y = 15 + x;
z = 20;
// System.out.println("Value of x is: " + x);
// System.out.println("Value of y is: " + y);
System.out.println("Values x and y are not accessible in static block");
}
}
public class StaticInitBlockDemo {
public static void main(String args[]) {
System.out.println("value of z is: " + StaticInitBlock.z);
}
}
Here, the commented code in the above example shows that the non-static variables can not be initialized in the static initialization block. Here is the output -

Static Initialization Block
Values x and y are not accessible in static block
value of z is: 20

Here is the link for example code at Github.