Thursday, 18 April 2013

Polymorphism in Java

Before we begin learning what is polymorphism and how is it useful let us step back and see how references and objects are created in Java.

Consider following line of Code

Dog myDog = new Dog();

It may look like a simple instance creation but includes multiple statements.
So when we say Dog myDog = new Dog() what actually happens is as follows - myDog is a reference(or you can visualize it as a pointer) which can refer to an object of type Dog. Note this reference is on the stack and not on the heap. When we use the new operator object is allocated memory on the heap and the reference points to this object. This is when we say object is created.

Important point to note here is that the reference type and the object type are the same i.e both are of type Dog.

But with polymorphism reference type and the object type can be different!!

All of polymorphism can be stated in a single line. Do keep this statement in mind -
"Super class reference for subclass object"

This means reference type mentioned above can be any super class of the subclass object to which it is pointing.

So if we have Class Dog extends Animal which means Animal is the super class of Dog then we can say
Animal myDog = new Dog(); 

To explain this further let us take an example -
Lets say we have an array of type Animal 

Animal[] animals = new Animal[5];

This means we have 5 references of type Animal
Now if Dog,Cat,Lion,Tiger,Wolf are subclasses of Animal then we can say -

animals[0] = new Dog(); 
animals[1] = new Cat();  
animals[2] = new Lion(); 
animals[3] = new Tiger(); 
animals[4] = new Wolf(); 

So we have multiple object references in the same array. Realizing the usefulness of polymorphism yet? Well there is more to come.
    
Now lets say we do something like -

for(int i=0; i< animals.length; i++)
{
    animals[i].eat();
} 

What happens now?At runtime JVM will figure out that animals[i] say animals[0] refers to object of type Dog and call the .eat() function in Dog class. But there is a catch .eat() function must be defined in Animal class.  You must define a function in the super class and then you may override it in sub class according to your implementation.

You can use polymorphism in passing arguments in a function as well as while returning values.
Example -

public void feedAnimal(Animal animal){//implementation}
or
public Animal getPet(String sound)
{
   if(sound.equals("bark"))
    {
         Dog myDog = new Dog();
         return  myDog;
     } 
    // more code 
}

I hope you get the point of polymorphism by now. You need not create separate function getPet() for each type of Animal or you need not create feedAnimal() function for each type of Animal.



Polymorphism will be used in a lot of codes without mentioning. We will refer to this post whenever possible but keep this concept in mind.

Sunday, 14 April 2013

Interview Question #8 What happens when a class implements two interfaces with same method?

This is a very interesting question. If you still don't get it let me give an example to explain it further -
We have two interfaces  - InterfaceA and InterfaceB. Then we have a concrete class which implements these interfaces.

Code of InterfaceA

package testCodes;

public interface InterfaceA {
    public void color();
}


Code for InterfaceB

package testCodes;

public interface InterfaceB {
    public void color();
}


Code for class ConcreteClass

package testCodes;

public class ConcreteClass implements InterfaceA, InterfaceB {
    public void color() {
        System.out.println("Red");
    }
}


Note that though we have same method in both interface we need to implement it only once in our concrete subclass. So it does not matter if we have two interfaces with same method. It will be implemented only once.

Problem arises when.....

   Problem will arise when there are two interfaces having method with same name and parameter but different return type. When a class will implement these two interface it will have to implement these two methods with same name and parameters but different return type. But this is not allowed. JVM will not allow this code to be compiled. Functions can have same name(function overloading) but they must have different signatures(different parameters.)



Inheritance in Java

When we said Java is an Object oriented programming language we mentioned some of it's features like Inheritance, polymorphism, Data Encapsulation etc.In this tutorial we will see what is inheritance, why do we need it and how do we use it in Java.

Why do we need inheritance?

Lets say you want to make different classes like Dog, Cat, Lion, Tiger etc. Each class will have some common attributes like food,picture,location etc. and some common methods like eat(), makeNoise() etc.
To avoid duplicate code we create a common class with common code(variables and functions) and then make other requires classes as subclasses of animal class.

So we need inheritance to avoid duplication of code and make our program more sensible and understandable.

Understanding inheritance in Java

   It is very simple to use inheritance in Java. Keyword that we use in this context is extends. A subclass extends a super class.Before looking at how to actually use it it is very important to decide when can we use inheritance? There is a simple 

IS-A Test : When ever you want to decide if inheritance is applicable, You can always use this test. So in above case we say Dog is an Animal, Tiger is an animal.. and so on.

 Let us see now how do we actually use inheritance in Java..

First we write class  Animal which is the super class.

package animalsData;

public class Animal {

    public String food;
    public String noise;

    public void run() {
        System.out.println("Running");
    }
}

Then we write the subclass Dog

package animalsData;

public class Dog extends Animal {
   
    public void eat()
    {
        System.out.println("Eating bone \n");
    }
}

and finally the Coordinator class to run our code.

package animalsData;

public class Coordinator {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat();
        dog.run();
    }
}
output : Eating bone
             Running

eat() is a function  of class Dog whereas run() is a function of class Animal which is inherited by class Dog.
We can inherit any such class by using extends keyword. Note that Java does not support multiple inheritance. This means that a single subclass cannot inherit from multiple subclasses. To avoid duplicate data in Java we can also use interfaces which we will see in our next tutorial.

Remember to apply IS-A test to indentify inheritance.

If Class 'X' extends Class 'Y' then Class 'X' IS-A 'Y'. This holds true in the entire inheritance tree. So if 'X' extends 'Y' and 'Z' extends X then 'Z' IS-A 'Y'.

Why multiple inheritance is not supported in Java?

  Java does not support multiple inheritance for the sake of simplicity for which it is built. Consider the Diamond problem of multiple inheritance - 



We have two classes B and C inheriting from A. Assume that B and C are overriding an inherited method and they provide their own implementation. Now D inherits from both B and C doing multiple inheritance. D should inherit that overridden method, which overridden method will be used? Will it be from B or C? Here we have an ambiguity.

Java provides means to tackle this and that is interfaces.
We will see interfaces in our next tutorial. 

Saturday, 13 April 2013

Understanding equals() and hashCode() methods in Java.

You must have heard that whenever you write a class of your own, you must always override equals() and hashCode()  methods.Lets us understand these methods and why it is important to override these methods.

Both these methods are defined in the Object class which is the top most class in the inheritance hierarchy. All classes implicitly extend object class and hence all class have these methods. Hence you must override these methods to suit your class requirements. Why and where they are used - we will come to it in some time.

Understanding motive behind the functions

     .equals() method is used to compare two objects. Since you only know the structure of your class you are the only one who can implement the comparison logic. For more details on this you can refer post on .equals() method. 

   .hashCode() method is used to return a unique integer value for each unique object. This unique number is used in various cases like while storing the objects in Map etc.So the motive is if two objects are same i.e if they return true on .equals() method then they must also return the same hashcode. So logic similar to .equlas() must be added to return a unique integer(hashcode) for unique objects.

Note : Reverse is not true. If two objects return the same hashcode they may or may not be same objects.

Default Implementation

public boolean equals(Object object) {
    return this == object;
}

public int hashCode() {
    return VMMemoryManager.getIdentityHashCode(this);
}

Summary

   Both your equals() and hashCode() are implementations of the programmer. Make sure to use same attributes in both these function. Whenever you override equals() method make it a point to override
hashCode() too. Key point to remember is if two objects are same they must return true from .equals() method and also they must return same hashcode from .hashCode() method.

If you are using an IDE like eclipse you can directly generate hashCode() and equals() just like generating getter and setter methods.Then add your overriding logic. Here is a snapshot of eclipse - 


Difference between using == operator and equals() method in Java

This is a very basic question and most frequently asked in interviews.  It is very important to understand the difference before you write complex Java programs.

   Let us start with == operator first.We know this is a comparator operator but the question is how does it actually work and how is it different from .equals() method?

== operator

       == operator compares whether the two references that are compared point to the same object or not. Result will be true if both references point to the same object else it is false.Lets take an example to understand this better.

package testCodes;

public class Test {
   
    public static void main(String args[])
    {
        String name1 = new String("John");
        String name2 = name1;
        if(name1 == name2)
        {
            System.out.println("Both references point to the same object \n");
        }

        else

        {   

            System.out.println("Both references point to different objects \n");

         }
    }
}

output : Both references point to the same object

In above code we create a String object name1 with value John. Then we create a reference name2 and make it point to the same object created earlier. Then we compare both references and as both references point to same object with value John == operator return true and hence we get our desired output. Lets say we do something like below -

String name1 = new String("John");

String name2 = new String("John");

if(name1 == name2)

{
    System.out.println("Both references point to the same object \n");

} 

else

{   

    System.out.println("Both references point to different objects \n");

}


 output : Both references point to different objects

As expected if we create two different objects, though both contain the same value John we get false from == operator as references point to two different object and else part is printed.

Note if you do something like

String name1 = "John";

String name2 = "John";

if(name1 == name2)

{
    System.out.println("Both references point to the same object \n");

} 

else

{   

    System.out.println("Both references point to different objects \n");

}


 output : Both references point to the same object

This is because when you don't create explicit objects, Java internally stores this data in a pool on the heap and any string created with  John as the value will point to this data in the pool.This is data is stored in an object called interned String objec. Hence they refer to same object and == return true. For more details refer the tutorial on Difference between String Object and String Literal.

To sum this up == operator check whether the two references which are being compared point to same object or not.

.equals() method

     This method is very much straight forward. It will simple check if the two objects are internally same or not. In case of String it will check if both objects have same value or not. If you are creating an object of your own you must override this  method to handle equality.

The default implementation of .equals() method is as follows -  

public boolean equals(Object other) 
{ 
     return this == other;   
} 

Yes that's right! By default .equals() method is same as using == operator. Hence for custom classes you must override this method by adding logic to compare  your objects.

For example if you are making a Coordinate class which has x and y coordinates as instance variable you may override .equals() method as follows - 


public boolean equals(Object other) 
{ 
     if((Coordinate)other.x == this.x  && (Coordinate)other.y == this.y)
     {
         return true;
      }
    else
     {
        return false;
      } 
} 

Above code just compare if x coordinate and y coordinate of both coordinate objects are same. If yes then the objects are similar and true is returned else false is returned. I hope you get the point.Also don't forget to override hashCode()method. We will learn this hashCode() method and why to override this in next tutorials but for now just keep that in mind.



Summary


    == operator check whether both the objects compared point to the same object or not while .equals() method is overridden and implemented by the programmer. .equals() method is provide to provide functionality to compare similarity of two objects. If it is not overridden then it is same as using ==  operator.


Related Links




t> UA-39527780-1 back to top