How to use Interface

Lab Overview

In the previous lab (GLAB - 303.10.3), we demonstrated that an abstract class has both methods with bodies, and methods with no bodies (abstract methods). You learned that abstract methods must be overridden in a subclass.

Learning Objective:

By the end of this lesson, learners will be able to use Java interfaces.

An Interface is similar to an abstract class with no fields, and all abstract methods. Interfaces cannot be instantiated — they can only be implemented by classes. The purpose of an Interface is to specify behavior for a class. In other words, we can say that an Interface is a design contract. It specifies methods and classes that can "implement" the Interface, and thereby sign the contract. We will use the Shapes example in this lab. Suppose that our application involves many shapes that can move. We could define an interface as movable, containing the signatures of the various movement methods.

Begin

Create a class named Shape. This will be an Abstract class and a Super class. Write the code below:

public abstract class Shape {
   protected String color;
   protected double height;  // To hold height.
   protected double width;  //To hold width
   protected double base;  //To  hold base

   public void setColor(String color) {
       this.color = color;
   }

   public void setWidth(double width) {
       this.width = width;
   }

   public void setHeight(double height) {
       this.height = height;
   }

   public void setBase(double base) {
       this.base = base;
   }

   // The getArea method is abstract.
   // It must be overridden in a subclass.
   /** All shapes must provide a method called getArea() */
   public abstract double getArea();

   /** Returns a self-descriptive string */
   public String toString() {
       return "Shape[color=" + color + "]";
   }

   public void displayshapName() {
       System.out.println("I am a Shape.");
   }
}

Create an Interface named Movable. It is similar to creating a new class, as shown below:

public interface Movable {
   // An interface defines a list of public abstract methods to be implemented by the subclasses
   void moveUp();    // "public" and "abstract" by default
   void moveDown();
   void moveLeft();
   void moveRight();
   String getCoordinate();
}

Similar to an abstract class, an Interface cannot be instantiated because it is incomplete (the abstract methods' body is missing). To use an interface, you must derive subclasses and provide implementation to all of the abstract methods declared in the interface. The subclasses are now complete and can be instantiated. To derive subclasses from an interface, a new keyboard "implement" is to be used instead of "extends" for deriving subclasses from an ordinary class or an abstract class. It is important to note that the subclass implementing an interface needs to override ALL abstract methods defined in the interface; otherwise, the subclass cannot be compiled.

Create a class named Circle. This will be a Child class. Write the code below. The new constructor will add in the Circle class for coordinates and radius.

public class Circle extends Shape implements Movable {
   protected double radius;
   private int x, y;   // x and y coordinates of the point
   private final double PI = Math.PI;

   /** Constructs a MovablePoint instance at the given x and y */
   public Circle(int x, int y, double radius) {
       this.x = x;
       this.y = y;
       this.radius = radius;
   }

   public Circle(double radius) {
       this.radius = radius;
   }

   public Circle(double radius, double height) {
       this.radius = radius;
       super.height = height;
   }

   @Override
   public double getArea() {
       //double area = PI * this.radius * this.radius;
       double area = PI * Math.pow(this.radius, 2); // initializing value in parent class variable
       return area; //reference to  parent class variable
   }

   @Override
   public void displayshapName() {
       System.out.println("Drawing a Circle of radius " + this.radius);
   }

   /** Returns a self-descriptive string */
   @Override
   public String toString() {
       return "Circle[ radius = " + radius + super.toString() +  "] ";
   }

   public String getCoordinate() {
     return  "(" + x + "," + y + ")";
   }

   // Need to implement all the abstract methods defined in the interface Movable
   @Override
   public void moveUp() {
       y--;
   }

   @Override
   public void moveDown() {
       y++;
   }

   @Override
   public void moveLeft() {
       x--;
   }

   @Override
   public void moveRight() {
       x++;
   }
}

Create a class named myRunner. This will be the Main class or entry point for the application. Write the code below.

public class myRunner {
   public static void main(String[] args) {

     Circle c1 = new Circle(1, 2, 2);
     System.out.println("Area of Circle " + c1.getArea());
     System.out.println("Coordinates are " + c1.getCoordinate());

     c1.moveDown();
     System.out.println("After move Down, Coordinates are " + c1.getCoordinate());

       c1.moveRight();
       System.out.println("After move right, Coordinates are " + c1.getCoordinate());

       c1.moveUp();
       System.out.println("After move Up, Coordinates are " + c1.getCoordinate());

       c1.moveLeft();
       System.out.println("After move left, Coordinates are " + c1.getCoordinate());

       System.out.println("--------Test Polymorphism-------");
       Movable c2 = new Circle(5, 10, 200);  // upcast
       c2.moveUp();
       System.out.println("After move up , Coordinates are " + c2.getCoordinate());

       c2.moveLeft();
       System.out.println("After move Left , Coordinates are " + c2.getCoordinate());
    }
}

We can also upcast subclass instances to the Movable interface via Polymorphism, similar to an abstract class.

Practice Task: Create two classes: Rectangle and Triangle. Extend both classes from the Shape class, and give an implementation of the Movable interface.

Last updated