Search Logic Blocks

Monday, December 14, 2020

Java: Partial Implementation of the Interface

Any class, which does not implement all the methods of an interface, must be declared as an abstract class. And any class which inherits the above abstract class, should implement the rest of the methods of the interface or should be abstract itself.

By using the example from the earlier post, I have created an abstract class called Quadrilateral. And the classes Rectangle, Square and Trapezoid are the subclasses of class Quadrilateral. The class Quadrilateral only defines the number of sides, which is the same for all the quadrilateral shapes.

As mentioned above, the class Quadrilateral doesn't implement all the methods from the interface IPolygon, so the class is declared as an abstract class. The classes inherited from the abstract class Quadrilateral, have implemented all the methods from the interface IPolygon.
// Interface Polygon gives structure of the methods needed to work with any polygon
// Every class implementing this interface should have all the methods
public interface IPolygon {
// Returns the text telling what shape it is
public String whatShape();

// Returns the numbers of sides
public int noOfSides();

// Returns the array of lengths of all sides
public double[] getSides();

// Returns the area of the shape
public double area();

// Returns the perimeter of the shape
public double perimeter();
}
// Abstract Class Quadrilateral implementing the class IPolygon
public abstract class Quadrilateral implements IPolygon {
final int noOfSides = 4;

public int noOfSides() {
return noOfSides;
}
}
// Class Rectangle subclass of class Quadrilateral
public class Rectangle extends Quadrilateral {
double side1;
double side2;
double perimeter;
double area;

// Rectangle Constructor with no arguments
Rectangle() {
this.side1 = 6;
this.side2 = 4;
}

// Rectangle Constructor with two arguments
Rectangle(double side1, double side2) {
this.side1 = side1;
this.side2 = side2;
}

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

// Returns the array of lengths of all sides
public double[] getSides() {
double arrSides[] = new double[4];
arrSides[0] = side1;
arrSides[1] = side2;
arrSides[2] = side1;
arrSides[3] = side2;
return arrSides;
}

// Returns the area of the rectangle
public double area() {
double pr;
pr = side1 * side2;
area = Math.round(pr * 100) / 100.0;
return area;
}

// Returns the perimeter of the rectangle
public double perimeter() {
perimeter = Math.round((2 * (side1 + side2)) * 100) / 100.0;
return perimeter;
}
}
// Class Square subclass of class Quadrilateral
public class Square extends Quadrilateral {
double side;
double perimeter;
double area;

// Square Constructor with no arguments
Square() {
this.side = 6;
}

// Square Constructor with three arguments
Square(double side) {
this.side = side;
}

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

// Returns the array of lengths of all sides
public double[] getSides() {
double arrSides[] = new double[4];
arrSides[0] = side;
arrSides[1] = side;
arrSides[2] = side;
arrSides[3] = side;
return arrSides;
}

// Returns the area of the Square
public double area() {
double pr;
pr = side * side;
area = Math.round(pr * 100) / 100.0;
return area;
}

// Returns the perimeter of the Square
public double perimeter() {
perimeter = Math.round(4 * side * 100) / 100.0;
return perimeter;
}
}
// Class Trapezoid subclass of class Quadrilateral
public class Trapezoid extends Quadrilateral {
double side1;
double side2;
double lbase; // Long Base
double sbase; // Short Base
double height; // Height of trapezoid
double perimeter;
double area;

// Trapezoid Constructor with no arguments
Trapezoid() {
this.side1 = 15;
this.side2 = 20;
this.lbase = 55;
this.sbase = 30;
this.height = 12;
}

// Trapezoid Constructor with four arguments
Trapezoid(double side1, double side2, double lbase, double sbase, double height) {
this.side1 = side1;
this.side2 = side2;
this.lbase = lbase;
this.sbase = sbase;
this.height = height;
}

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

// Returns the array of lengths of all sides
public double[] getSides() {
double arrSides[] = new double[4];
arrSides[0] = side1;
arrSides[1] = side2;
arrSides[2] = lbase;
arrSides[3] = sbase;
return arrSides;
}

// Returns the area of the Trapezoid
public double area() {
double pr;
pr = (lbase + sbase) / 2 * height;
area = Math.round(pr * 100) / 100.0;
return area;
}

// Returns the perimeter of the Trapezoid
public double perimeter() {
perimeter = side1 + side2 + lbase + sbase;
perimeter = Math.round(perimeter * 100) / 100.0;
return perimeter;
}
}
// Class for testing the interface IPolygon and its implementing classes
public class PolygonTest {
public static void main(String args[]) {
IPolygon P[] = new IPolygon[4];
P[0] = new Square(9);
P[1] = new Rectangle(18, 11);
P[2] = new Trapezoid(7, 5, 8, 6, 4);
P[3] = new Trapezoid();

for(int i = 0; i < P.length; i++) {
System.out.println("Polygon " + (i+1) + " is " + P[i].whatShape());
System.out.println("No of sides: " + P[i].noOfSides());
double allSides[] = P[i].getSides();
System.out.print("All sides are : ");
for(int j = 0; j < allSides.length; j++) {
System.out.print("Side" + (j+1) + ": " + allSides[j] + " ");
}
System.out.println();
System.out.println("Perimeter is : " + P[i].perimeter());
System.out.println("Area is : " + P[i].area());
System.out.println();
}
}
}
Here is the output for above code:

Polygon 1 is Square
No of sides: 4
All sides are : Side1: 9.0   Side2: 9.0   Side3: 9.0   Side4: 9.0   
Perimeter is : 36.0
Area is : 81.0

Polygon 2 is Rectangle
No of sides: 4
All sides are : Side1: 18.0   Side2: 11.0   Side3: 18.0   Side4: 11.0   
Perimeter is : 58.0
Area is : 198.0

Polygon 3 is Trapezoid
No of sides: 4
All sides are : Side1: 7.0   Side2: 5.0   Side3: 8.0   Side4: 6.0   
Perimeter is : 26.0
Area is : 28.0

Polygon 4 is Trapezoid
No of sides: 4
All sides are : Side1: 15.0   Side2: 20.0   Side3: 55.0   Side4: 30.0   
Perimeter is : 120.0
Area is : 510.0

You can find code at Github link.

Saturday, December 12, 2020

Java: Interfaces

What is an Interface?
We have already discussed about the abstract methods and abstract classes. Abstract methods (empty methods) are declared in the superclass, but the body of the method is written in the subclass. The subclass must define all the abstract methods given in the super class. An abstract method acts like a prototype.

Interface is also like an abstract class, where all the method bodies (except default and static methods) are empty (or abstract) and an interface can not be instantiated like a regular class. Interfaces can only be implemented by other classes or can be extended by other interfaces. One class can implement more than one interface. The class, which implements the interface, should have implementation of all the methods available in the interface.

How to declare an Interface -
Interface is declared by using a keyword interface followed by the interface name. The interfaces can have only the method signatures or declarations. Following code is an example of interface IPolygon and its implementation in two classes - Triangle nad Rectangle and one demo class - PolygonTest.
// Interface Polygon gives structure of the methods needed to work with any polygon
// Every class implementing this interface should have all the methods
public interface IPolygon {
// Returns the text telling what shape it is
public String whatShape();

// Returns the numbers of sides
public int noOfSides();

// Returns the array of lengths of all sides
public double[] getSides();

// Returns the area of the shape
public double area();

// Returns the perimeter of the shape
public double perimeter();
}
// Class Triangle implementing the interface IPolygon
public class Triangle implements IPolygon {
final int noOfSides = 3;
double side1;
double side2;
double side3;
double perimeter;
double area;

// Triangle Constructor with no arguments
Triangle() {
this.side1 = 4;
this.side2 = 4;
this.side3 = 4;
}

// Triangle Constructor with three arguments
Triangle(double side1, double side2, double side3) {
this.side1 = side1;
this.side2 = side2;
this.side3 = side3;
}

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

// Returns the numbers of sides
public int noOfSides() {
return noOfSides;
}

// Returns the array of lengths of all sides
public double[] getSides() {
double arrSides[] = new double[3];
arrSides[0] = side1;
arrSides[1] = side2;
arrSides[2] = side3;
return arrSides;
}

// Returns the area of the triangle
public double area() {
double p, diff1, diff2, diff3, pr;
p = perimeter / 2;
diff1 = p - side1;
diff2 = p - side2;
diff3 = p - side3;
pr = p * diff1 * diff2 * diff3;
area = Math.round(Math.sqrt(pr) * 100) / 100.0;
return area;
}

// Returns the perimeter of the triangle
public double perimeter() {
perimeter = Math.round((side1 + side2 + side3) * 100) / 100.0;
return perimeter;
}
}
// Class Rectangle implementing the interface IPolygon
public class Rectangle implements IPolygon {
final int noOfSides = 4;
double side1;
double side2;
double perimeter;
double area;

// Rectangle Constructor with no arguments
Rectangle() {
this.side1 = 4;
this.side2 = 4;
}

// Rectangle Constructor with three arguments
Rectangle(double side1, double side2) {
this.side1 = side1;
this.side2 = side2;
}

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

// Returns the numbers of sides
public int noOfSides() {
return noOfSides;
}

// Returns the array of lengths of all sides
public double[] getSides() {
double arrSides[] = new double[4];
arrSides[0] = side1;
arrSides[1] = side2;
arrSides[2] = side1;
arrSides[3] = side2;
return arrSides;
}

// Returns the area of the rectangle
public double area() {
double pr;
pr = side1 * side2;
area = Math.round(pr * 100) / 100.0;
return area;
}

// Returns the perimeter of the rectangle
public double perimeter() {
perimeter = Math.round((2 * (side1 + side2)) * 100) / 100.0;
return perimeter;
}
}
// Class for testing the interface IPolygon and its implementing classes
public class PolygonTest {
public static void main(String args[]) {
IPolygon P[] = new IPolygon[2];
P[0] = new Triangle(16.6, 11.2, 17.9);
P[1] = new Rectangle(12.5, 15.5);

for(int i = 0; i < P.length; i++) {
System.out.println("Polygon " + (i+1) + " is " + P[i].whatShape());
System.out.println("No of sides: " + P[i].noOfSides());
double allSides[] = P[i].getSides();
System.out.print("All sides are : ");
for(int j = 0; j < allSides.length; j++) {
System.out.print("Side" + (j+1) + ": " + allSides[j] + " ");
}
System.out.println();
System.out.println("Perimeter is : " + P[i].perimeter());
System.out.println("Area is : " + P[i].area());
System.out.println();
}
}
}
In this case, the interface is  declared as public, so any class, which is inside and outside of the package, can implement the interface. When there is no access modifier, the interface can be only accessed by the classes inside the package in which the interface is defined. The interface methods are declared like the variables and declaration statement is ended by a semicolon (;).

Variables can be declared inside the interface, but they must be initialized and they are implicitly final and static. The variables defined in the interface can not be changed (final) and can be accessed by interface (static) itself. All the members of the interface are implicitly public.

How to implement an Interface -
To implement an interface, implements clause is used in the class definition and all the methods are implemented in the class. One class can implement any number of interfaces by having all the interface names separated by commas.

The classes Triangle and Rectangle, both have implemented all the methods declared in the interface and they have their own implementations. Interface can not have its own constructor, as the interface can not be instantiated. But the classes implementing the interface can have their own constructors.

How to access Interface Methods -
Interface methods can be accessed through the implementing class in the same way as we access the regular class methods. But interface methods can also be accessed by reference as we access superclass methods by reference. In the above example, in the class PolygonTest, the interface methods are accessed only by reference. There is an array of interface class objects and the object references of classes Triangle and Rectangle are assigned to the array element.

When the loop is run at run-time, the program decides what type of object is referred and the method of that class is run dynamically. But the interface reference object can only call methods declared in the interface, but not the other methods defined in the class referred to.

Here is the output of above code-

Polygon 1 is Triangle
No of sides: 3
All sides are : Side1: 16.6   Side2: 11.2   Side3: 17.9   
Perimeter is : 45.7
Area is : 90.75

Polygon 2 is Rectangle
No of sides: 4
All sides are : Side1: 12.5   Side2: 15.5   Side3: 12.5   Side4: 15.5   
Perimeter is : 56.0
Area is : 193.75

Code can be get at Github link.