Tuesday, April 28, 2020

Java docstring Override


 Base class that defines the method getArea that will be overriden by its child class.  This post will explore the annotation that should be used when overriding methods.

@Override is an annotation ( note the capital O )

Annotations, a form of metadata, provide data about a program that is not part of the program itself. Annotations have no direct effect on the operation of the code they annotate.
Annotations have a number of uses, among them:
  • Information for the compiler — Annotations can be used by the compiler to detect errors or suppress warnings.
  • Compile-time and deployment-time processing — Software tools can process annotation information to generate code, XML files, and so forth.
  • Runtime processing — Some annotations are available to be examined at runtime.
ref: https://docs.oracle.com/javase/tutorial/java/annotations/index.html 

Let's create a simple example that you can compile, run, and experiment with to learn the usage of the @Override annotation.

Like with any code, you should start by creating a UML ( in this case, a simplified UML).


/**
 * The Rectangle class stores and manipulates
 * data for a rectangle.
 */


public class Rectangle{
     protected double length;
     protected double width;

    /**
     * Overloaded constructor
     * @param len sets the length field
     * @param w sets the width field
     */

     public Rectangle(double len, double w){
          length = len;
          width = w;
     }

    /**
     * The getArea method returns the value of the
         * length field times the width field.
         * @return the are of the rectangle
     */

     public double getArea() {
          return length * width;
     }
}

And the derived class will be the Box class that will override the getArea method.

/**
 * Extends the Rectangle class to demonstrate the @Override annotation
 */

public class Box extends Rectangle
{
 private double height;
  
 /**
  * Parameterized Constructor
  * @param length
  * @param width
  * @param height
  */

 public Box(double length, double width, double height){
     super(length, width);
     this.height=height;
    }
  

 /**
  * This is is the description from the method that overriden the inherited method
  * @return the surface area of the box ( note: floor and ceiling are will be included )
  */

 @Override
  public double getArea(){
     return 2*(super.getArea() + height*(length+width));
    }
}

The driver is a simple class

  /**
   * Application to calculate the paint needed to paint a house.
   */

public class HousePaintDemo {

public static void main(String args[]){

Box myHouse=new Box(8,10,9);//in feet

System.out.println("You house will need "+myHouse.getArea()+"sqft of paint.");
System.out.printf("One gallon can of paint will cover up to 400 square feet, so you will need %4.0f gallons of paint.\n",Math.ceil(myHouse.getArea()/400*1.1));
}
}

So, why do need the @Override annotation? The answer is simple, you need to look at the documentation and modify the parent method with or without the @Override annotation to see the answer.

Remove the @Override annotation in front of the getArea method in the Box class.  Generate the documentation and read the resulting html page.

  • Method Detail

    • getArea

      public double getArea()
      This is is the description from the method that overriden the inherited method
      Overrides:
      getArea in class Rectangle
      Returns:
      the surface area of the box ( note: floor and ceiling are will be included )
You can see the documentation is not very helpful since it is not the documentation we wrote for the overriden method. The result is the same if you do not use the annotation properly when it comes to docstrings.

Wrong usage

 @Override
 /**
  * This is is the description from the method that overriden the inherited method
  * @return the surface area of the box ( note: floor and ceiling are will be included )
  */

  public double getArea(){
     return 2*(super.getArea() + height*(length+width));
    }

The annotation must be just before the method header and after the docstring.








Proper usage
 
 /**
  * This is is the description from the method that overriden the inherited method
  * @return the surface area of the box ( note: floor and ceiling are will be included )
  */

 @Override
  public double getArea(){
     return 2*(super.getArea() + height*(length+width));
    }

In this case, the documentation will reflect the proper documentation from the derived class.

  • Method Detail

    • getArea

      public double getArea()
      This is is the description from the method that overriden the inherited method
      Overrides:
      getArea in class Rectangle
      Returns:
      the surface area of the box ( note: floor and ceiling are will be included )
Now, is there any other usage for this annotation? ", You might ask.  the answer is, yes.  Methods in the derived class can have any headers, so if the parent class method header changes, how would the child know that it also need to change.  The @Override annotation forces the compiler to match the method headers from the child to the parent.  Thus, it is a safety annotation that should always be used when overriding methods.

Test it:
Try to change the getArea method in the Rectangle class to return an integer not a double and see if you can still compile the code.

     public int getArea() {
          return (int)(length * width);
     }

Now, when you try to compile the application, it will not compile and the @Override annotation should remind you to update the failed methods.  So, fix the getArea method so it also return an integer.

  • Method Detail

    • getArea

      public int getArea()
      This is is the description from the method that overriden the inherited method
      Overrides:
      getArea in class Rectangle
      Returns:
      the surface area of the box ( note: floor and ceiling are will be included )
Now, you know it all!