Classes and Objects in Java

There are many differences between method overloading and method overriding in java. A list of differences between method overloading and method overriding are given below:

Objects have states and behaviors. Example: A dog has states – color, name, breed as well as behaviors – wagging the tail, barking, eating. An object is an instance of a class.

Class − A class can be defined as a template/blueprint that describes the behavior/state that the object of its type support.

Overloading Methods

Sometimes the same functionality has to be written for different kinds of inputs. At that time, one can use the same method name with a different set of parameters. Each different set of parameters is known as a method signature. As seen per the example, a single method can have multiple signatures.

public class Displayer {

       public void displayName(String firstName) {
            System.out.println("Name is: " + firstName);
       }
       public void displayName(String firstName, String lastName) {
           System.out.println("Name is: " + firstName + " " + lastName);
}
public static void main(String[] args) {
          Displayer displayer = new Displayer();
          displayer.displayName("Ram"); //prints "Name is: Ram"
          displayer.displayName("Jon", "Skeet"); //prints "Name is: Jon Skeet"
         }
}

The advantage is that the same functionality is called with two different numbers of inputs. While invoking the method according to the input we are passing, (In this case either one string value or two string values) the corresponding method is executed.

Methods can be overloaded:

  1. Based on the number of parameters passed.
Example: method(String s) and method(String s1, String s2).
  1. Based on the order of parameters.
Example: method(int i, float f) and method(float f, int i)).

Note: Methods cannot be overloaded by changing just the return type (int method() is considered the same as the String method() and will throw a RuntimeException if attempted). If you change the return type you must also change the parameters in order to overload.

Explaining what is method overloading and overriding

Method Overriding and Overloading are two forms of polymorphism supported by Java.

Method Overloading

Method overloading (also known as static Polymorphism) is a way you can have two (or more) methods (functions)
with same name in a single class. Yes its as simple as that.

public class Shape{
       //It could be a circle or rectangle or square
       private String type;
       //To calculate area of rectangle
       public Double area(Long length, Long breadth){
            return (Double) length * breadth;
       }
       //To calculate area of a circle
       public Double area(Long radius){
       return (Double) 3.14 * r * r;
       }
}

This way user can call the same method for area depending on the type of shape it has.

But the real question now is, how will java compiler distinguish which method the body is to be executed?

Well, Java has made it clear that even though the method names (area() in our case) can be the same but the arguments method is taking should be different.

Overloaded methods must have different arguments list (quantity and types).

That being said we cannot add another method to calculate the area of a square like this: public Double area(Long side) because in this case, it will conflict with area method of the circle and will cause ambiguity for java compiler.

Thank god, there are some relaxations while writing overloaded methods like

May have different return types, access modifiers and exceptions.

Why is this called static polymorphism?

Well that’s because which overloaded methods is to be invoked is decided at compile time, based on the actual
number of arguments and the compile-time types of the arguments.

One of the common reasons for using method overloading is the simplicity of code it provides. For example, remember String.valueOf() which takes almost any type of argument? What is written behind the

scene is probably something like this:
static String valueOf(boolean b)
static String valueOf(char c)
static String valueOf(char[] data)
static String valueOf(char[] data, int offset, int count)
static String valueOf(double d)
static String valueOf(float f)
static String valueOf(int i)
static String valueOf(long l)
static String valueOf(Object obj)

Method Overriding

Well, method overriding (yes you guessed it right, it is also known as dynamic polymorphism) is a somewhat more interesting and complex topic.

In method overriding we overwrite the method body provided by the parent class. Got it? No? Let’s go through an example.

public abstract class Shape{

    public abstract Double area(){
    return 0.0;
    }
}

So we have a class called Shape and it has a method called area which will probably return the area of the shape.

Let’s say now we have two classes called Circle and Rectangle.

public class Circle extends Shape {
      private Double radius = 5.0;
      // See this annotation @Override, it is telling that this    method is from parent
      // class Shape and is overridden here
      @Override
      public Double area(){
           return 3.14 * radius * radius;
      }
}

Similarly rectangle class:

public class Rectangle extends Shape {
       private Double length = 5.0;
       private Double breadth= 10.0;

       // See this annotation @Override, it is telling that this method is from parent
       // class Shape and is overridden here
       @Override
       public Double area(){
             return length * breadth;
       }
}

So, now both of your children classes have updated method body provided by the parent (Shape) class. Now
question is how to see the result? Well lets do it the old psvm way.

public class AreaFinder{

     public static void main(String[] args){

         //This will create an object of circle class
         Shape circle = new Circle();
         //This will create an object of Rectangle class
         Shape rectangle = new Rectangle();
         // Drumbeats ……
         //This should print 78.5
         System.out.println("Shape of circle : "+circle.area());
         //This should print 50.0
         System.out.println("Shape of rectangle: "+rectangle.area());
        }
}

Wow! isn’t it great? Two objects of the same type calling the same methods and returning different values. My friend, that’s the power of dynamic polymorphism.

Here’s a chart to better compare the differences between these two:

Method OverloadingMethod Overriding
Method overloading is used to increase the readability of the program.Method overriding is used to provide the specific implementation of the method that is already provided by its superclass.
Method overloading is performed within the class.Method overriding occurs in two classes that have IS-A (inheritance) relationship.
In case of method overloading, parameter must be different.In case of method overriding, the parameter must be the same.
Method overloading is the example of compile time polymorphism.Method overriding is the example of run time polymorphism.
In java, method overloading can’t be performed by changing return type of the method only. Return type can be same or different in method overloading. But you must have to change the parameter.The return type must be the same or covariant in method overriding.

Constructors

Constructors are special methods named after the class and without a return type and are used to construct objects. Constructors, like methods, can take input parameters. Constructors are used to initializing objects. Abstract classes can have constructors also.

public class Hello{
      // constructor
      public Hello(String wordToPrint){
          printHello(wordToPrint);
      }
      public void printHello(String word){
        System.out.println(word);
      }
}
// instantiates the object during creating and prints out the content
// of wordToPrint

It is important to understand that constructors are different from methods in several ways:

  1. Constructors can only take the modifiers public, private, and protected, and cannot be declared abstract, final, static, or synchronized.
  2. Constructors do not have a return type.
  3. Constructors MUST be named the same as the class name. In the Hello example, the Hello object’s constructor name is the same as the class name.
  4. This keyword has an additional usage inside constructors. this.method(…) calls a method on the current instance, while this(…) refers to another constructor in the current class with different signatures.

Constructors also can be called through inheritance using the keyword super.

public class SuperManClass{

      public SuperManClass(){
          // some implementation
      }
      // … methods
}

public class BatmanClass extends SupermanClass{
      public BatmanClass(){
           super();
      }
      //… methods…
}
Initializing static final fields using a static initializer

To initialize a static final fields that require using more than a single expression, a static initializer can be used to assign the value. The following example initializes a unmodifiable set of Strings:

public class MyClass {

     public static final Set WORDS;

     static {
        Set set = new HashSet<>();
        set.add("Hello");
        set.add("World");
        set.add("foo");
        set.add("bar");
        set.add("42");
        WORDS = Collections.unmodifiableSet(set);
        }
}

Leave a Comment