Saturday, 1 February 2014

Virtual Functions in Java

According to Virtual function definition: 
In object-oriented programming, a virtual function or virtual method is a function or method whose behaviour can be overridden within an inheriting class by a function with the same signature to provide the polymorphic behavior.

In Java, we can override all non-static , non-private , non-final methods within an inheriting class.

According to this, All non-static functions or methods in java are virtual by default. Private and final methods or functions are not virtual in java.

Methods in Interfaces and abstract classes are pure virtual methods. Because they are declared to be overridden.

Have a look on below example
interface Shape
{
  public int setLength(); // Pure Virtual function
}

public class Circle implements Shape
{
 @Override
  public int setLength() // can be overridden, so its virtual funtion
 {
         .................
         ................
 }
}

public class Animal
{
 public static void sound() // Its not a virual, static methods cannot be overridden
 {

 }
 public final void talk() // It is not a virtual , final methoda cannot be overridden
 {
   
 }
 public void height() // It is a virtual function
 {

 }
}

public class Cat extends Animal
{
 // statements
}

Friday, 31 January 2014

Is it possible to Override Static Method?

Obviously............ NO.

We cannot override static methods. We cannot change the behavior of static methods within an inheriting class.

When you are trying to override the final method you would get an compile time error, But when you try to override a static method you dont get any compile type errors but the behavior cannot be overridden.Yes you can write overridding code but the behavior cannot be overridden. Java dont stop you to do that.

Why static methods cannot be overridden is.. because they are class methods hence calling the static methods defined by compiler at compile time. they are not belongs to Object state.

Have a look at below example


public class ParentClass {
public static void staticMethod()
{
System.out.println("ParentClass Static Method");
}
}

public class ChildClass extends ParentClass {
public static void staticMethod()
{
System.out.println("ChildClass Static Method");
}
public static void main(String[] args) {
ParentClass parentClassWithChildObject = new ChildClass();
ParentClass.staticMethod();
parentClassWithChildObject.staticMethod(); //calls superclass staticMethod even thought it holds childClass object at runtime
ChildClass.staticMethod();
}
}

The output comes like
ParentClass Static Method
ParentClass Static Method
ChildClass Static Method

Note: We can overload static methods.

Thursday, 30 January 2014

Overridding equals and hashCode methods

According to the equal contract, If two objects are equal then hashCode of those two objects must return same integer.

If two objects are unequal there hashCode may or may not be same.

It is not neccessary overriding both at all time, But if you think to override one then you must override the other one too..

The problem occurs when we work with HashMap and Hashtables

In our previous post, Hashmap machanism we discussed that HashMap assigns key object hashCode to the bucket as identity. When we retrieve value from HashMap it finds the hashCode of the key and returns the value.
(Note: hashCode is nuthing but an integer number, by converting object memory address to an integer)

Lets see why to override both equals and hashCode methods.
in this below example, i am overriding only equals mehtod

public class Customer{
int id;
String name;
public Customer(int id, String name)
{
this.id = id;
this.name = name;
}
@Override
public boolean equals(Object obj) {
System.out.println("Calling");
if(null == obj)
return false;
if(!(this.getClass() == obj.getClass()))
return false;
if(!(this.id == ((Customer)obj).id && this.name.equals(((Customer)obj).name))
return false;
return true;
}
public static void main(String[] args) {
Customer customer = new Customer(1, "Prasad");
HashMap<Object, Object> map = new HashMap<Object, Object>();
map.put(customer, new String("123"));
System.out.println(map.get(new Customer(1, "Prasad"))); // returns null
}
}

In the above example, i am assigning Customer object as key and retrieves with the same Customer object. Eventhough i am retrieving with the new object, according to my equals method the two objects(storing and retrieving) are equal. because i am performing equality by overriding equals method, and based on the id and name it is performing equality.

The HashMap results null, because the two same objects has the different hashCodes.

So i must override hashCode method along with the equals method.

Now in this below example
public class Customer{
int id;
String name;
public Customer(int id, String name)
{
this.id = id;
this.name = name;
}
@Override
public boolean equals(Object obj) {
System.out.println("Calling");
if(null == obj)
return false;
if(!(this.getClass() == obj.getClass()))
return false;
if(!(this.id == ((Customer)obj).id && this.name.equals(((Customer)obj).name))
return false;
return true;
}
      @Override
public int hashCode() {
int num = 3;
return num*this.name.hashCode();
}
public static void main(String[] args) {
Customer customer = new Customer(1, "Prasad");
HashMap<Object, Object> map = new HashMap<Object, Object>();
map.put(customer, new String("123"));
System.out.println(map.get(new Customer(1, "Prasad"))); // returns 123
}
}

Now it returns the value as 123.

Because here the hashCodes are same for same equal objects.

HashMap Machanism

When you store the values in HashMap, the values are actually stored in a set of buckets. Each of those buckets has been assigned a number which is use to identify it. HashMap implementation calls hashCode method on Key object and assigns the key object hashcode number to bucket to identify it. When you put a value in the HashMap, it stores the data in one of those buckets. Which bucket is used depends on the hashCode that will return by your object. 

Important point to mention is that HashMap in Java stores both key and value object as Map.Entry in bucket which is essential to understand the retrieving logic.
What will happen if two different objects have same hashcode?

equals() and hashCode() contract  that two unequal object in Java can have same hashcode
Since hashcode is same, bucket location would be same and collision will occur in HashMap, Since HashMap use LinkedList to store object, this entry (object of Map.Entry comprise key and value )  will be stored in LinkedList.

Followers