Search Logic Blocks

Wednesday, June 24, 2020

Java: What is Inheritance?

I have already mentioned about the parent-child relationship between different classes earlier in the last post - Polymorphism, where class Shape was the parent class, and classes Circle, Triangle and Rectangle were the child classes of the class Shape.

Inheritance is basically a hierarchical classification. A parent class is created using all the common properties and behaviors for a set of related things. In Java, the parent class is called as a superclass or base class. Then child classes inherit all the properties and behaviors from the parent class (derived from the base class), and the child classes can have their own properties and behaviors in addition. The child class is also called as a subclass.

Let's examine our classes from last post - Shape, Circle, Triangle and Rectangle. Class Shape is the parent class or superclass and it has three variables (PI, width, height) and two methods (whatShape() and area()).

Class Shape (Shape.java)
// Parent class Shape
import java.lang.Math; // imports Math package
public class Shape {
final static double PI = Math.PI;
double width = 0;
double height = 0;

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

// Returns the area of the shape
public double area() {
return 0.0;
}
}
PI is final static double variable means, the value of variable PI can not be changed and can be accessed directly without creating any instance of the class. Every shape has width and height measurements, and are used to calculate shape's area. whatShape() method tells what shape it is, and area() method calculates the area of the shape.

Classes Circle, Triangle and Rectangle are child classes or subclasses. They are declared as child classes using the key-word extends. The subclasses are inheriting all the variables from the super class, but they have their own methods with the same names as in superclass. Having same name methods as in superclass is called overriding methods and is part of Java's Polymorphism principle as I mentioned in the last post - Polymorphism.

Class Circle (Circle.java)
// Child class Circle inherits from class Shape
public class Circle extends Shape{
// Returns the text telling what shape it is
public String whatShape() {
return "Circle";
}

// Returns the area of the shape - can access parent's declared variables
public double area() {
double radius = width / 2;
return Math.round(PI * radius * radius * 100) / 100.0;
}
}
Class Triangle (Triangle.java)
// Child class Triangle inherits from class Shape
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;
}
}
Class Rectangle (Rectangle.java)
// Child class Rectangle inherits from class Shape
public class Rectangle extends Shape {
// Returns the text telling what shape it is
public String whatShape() {
return "Rectangle";
}

// Returns the area of the shape - can access parent's declared variables
public double area() {
return Math.round(height * width * 100) / 100.0;
}
}
Class ShapesTest (ShapesTest.java)
// class ShapesTest to test class Shape's overridden methods - whatShape() and area()
public class ShapesTest {
public static void main(String args[]) {
// Created an array of 3 shapes
Shape shapes[] = new Shape[3];

// Created 3 instances of 3 child classes
shapes[0] = new Circle();
shapes[1] = new Triangle();
shapes[2] = new Rectangle();
System.out.println("Shapes Test");

for(int i = 0; i < shapes.length; i++) {
shapes[i].height = 5;
shapes[i].width = 9;

// Called the methods through parent's reference (Compiler doesn't know which object is called)
// At run-time decision is made, which class method is called
System.out.println("Shape is " + shapes[i].whatShape());
System.out.println("Area is " + shapes[i].area());
System.out.println("");
}
}
}
Output:

Shapes Test
Shape is Circle
Area is 63.62

Shape is Triangle
Area is 22.5

Shape is Rectangle
Area is 45.0

Let's add one more method isEllipse() and modify methods whatShape() and area() in subclass Circle -

Class Circle (Circle.java)
// Child class Circle inherits from class Shape
public class Circle extends Shape{
// Checks whether the circle is an ellipse
private boolean isEllipse() {
if(width != height) return true;
else return false;
}
// Returns the text telling what shape it is
public String whatShape() {
String sh = "";
if(isEllipse()) sh = "Ellipse";
else sh = "Circle";
return sh;
}

// Returns the area of the shape - can access parent's declared variables
public double area() {
double xradius = width / 2;
double yradius = height / 2;
return Math.round(PI * xradius * yradius * 100) / 100.0;
}
}
Output:

Shapes Test
Shape is Ellipse
Area is 35.34

Shape is Triangle
Area is 22.5

Shape is Rectangle
Area is 45.0
isEllipse() method checks whether the height and width are not same. If not, then shape is an ellipse. Accordingly, it shows shape text and calculates area. So, isEllipse() method is an additional method used only in subclass Circle. Superclass and other subclasses can not access the isEllipse() method. You can see the change in the output.

In the post Encapsulation, we discussed about access modifiers. In case of inheritance, if superclass has a variable or method with access modifier as private, the subclasses and any other classes can not access that variable or method. But if superclass has a variable or method with access modifier as protected, the subclasses and non-subclasses in the package and subclasses in other packages can access that variable or method, but non-subclasses which are not in the package, can not access the protected variable or method.

No comments: