Search My Blog

Thursday, June 28, 2012

why do we need runtime polymorphism

I know how to achieve runtime polymorphism through inheritance and through interfaces. But why do we need to have runtime polymorphism in the first place? I found a good explanation at Stack overflow :

http://stackoverflow.com/questions/2080020/what-is-the-real-significanceuse-of-polymorphism

Basically, interfaces allow you to use methods of a class, without getting into the details of the implementation(encapsulation?). This is achieved by using a reference of the interface to create an object of the implementing class. Now, all we need to do is call the methods of the class through the interface. This is where runtime polymorphism kicks in - determining the object whose method is to be called during runtime, instead of compile time.

DBOperation dbo =  null;  //DBOperation is an interface

if(system == "RDBMS")
  dbo = new RDBMS();  //RDBMS implements DBOperation
else
  dbo = new FileDB();  //FileDB implements DBOperation

dbo.openConnection(".....");
....

Here, the compiler does not know which object to instantiate, i.e., RDBMS() or FileDB(). It is decided during runtime, hence the concept of runtime polymorphism.

Now, back to why we need it.
As can be seen from the above example, when we have multiple implementations, and are not concerned about the actual implementation, but only want the functionality, we can define interfaces to exploit this functionality. This is most obvious in the List interface in Java.

"One other important use is, if you are using java, most of the time you would work on List interface, so that you can use ArrayList today or some other interface as your application grows or its needs change." - StackOverflow.


Wednesday, June 27, 2012

runtime polymorphism using interfaces in Java


(Source - Stack overflow)

Interfaces allow you to use classes across different hierarchies polymorphically.

For example, say you have the following interface:
public interface Movable {
    void move();
}
 
Any number of classes, across class hierarchies could implement Movable in their own specific way, yet still be used by some caller in a uniform way.

So if you have the following two classes:

public class Car extends Vehicle implements Movable {
    public void move() {
       //implement move, vroom, vroom!
    }
}
public class Horse extends Animal implements Movable {
    public void move() {
       //implement move, neigh!
    }
}

From the perspective of the caller, it's just a Movable
 
Movable movable = ...;
movable.move();  //who am I?

runtime polymorphism in java

(Source : http://www.xyzws.com/Javafaq/what-is-runtime-polymorphism-in-java/16)

Polymorphism is the capability of an action or method to do different things based on the object that it is acting upon. In other words, polymorphism allows you define one interface and have multiple implementation. This is one of the basic principles of object oriented programming.
The method overriding is an example of runtime polymorphism. You can have a method in subclass overrides the method in its super classes with the same name and signature. Java virtual machine determines the proper method to call at the runtime, not at the compile time.
Let's take a look at the following example:
class Animal {
  void whoAmI() {
    System.out.println("I am a generic Animal.");
  }
}
class Dog extends Animal {
  void whoAmI() {
    System.out.println("I am a Dog.");
  }
}
class Cow extends Animal {
  void whoAmI() {
    System.out.println("I am a Cow.");
  }
}
class Snake extends Animal {
  void whoAmI() {
    System.out.println("I am a Snake.");
  }
}

class RuntimePolymorphismDemo {

  public static void main(String[] args) {
    Animal ref1 = new Animal();
    Animal ref2 = new Dog();
    Animal ref3 = new Cow();
    Animal ref4 = new Snake();
    ref1.whoAmI();
    ref2.whoAmI();
    ref3.whoAmI();
    ref4.whoAmI();
  }
}
The output is
I am a generic Animal.
I am a Dog.
I am a Cow.
I am a Snake.
In the example, there are four variables of type Animal (e.g., ref1, ref2, ref3, and ref4). Only ref1 refers to an instance of Animal class, all others refer to an instance of the subclasses of Animal. From the output results, you can confirm that version of a method is invoked based on the actually object's type.
In Java, a variable declared type of class A can hold a reference to an object of class A or an object belonging to any subclasses of class A. The program is able to resolve the correct method related to the subclass object at runtime. This is called the runtime polymorphism in Java. This provides the ability to override functionality already available in the class hierarchy tree. At runtime, which version of the method will be invoked is based on the type of actual object stored in that reference variable and not on the type of the reference variable.

Monday, June 11, 2012

reverse an integer

int reverse(int num)  //works only for non neg numbers
{
  if(num < 0)
  {
     System.out.println("does not work for neg integers");
     return -1;
  }

  int rev = 0;
  while(num > 0)
  {
     rev = rev * 10 + num%10;
     num /= 10;
  }

  return rev;
}

can be used to check if a given number is palindrome.

Saturday, June 9, 2012

reverse a linked list(iterative approach)

//returns new head pointer
Node reverse(Node head)
{
//empty list
if(head == null) return;

//all other cases, including only 1 node in the list
Node current = head.next;
Node prev = head;
Node tmp = null;


head.next = null;

while(current != null)
{
  tmp = current.next;
  current.next = prev;
  prev = current;
  current = tmp;
}

return prev;  //new head
}

detecting a loop in a linked list

boolean hasLoop(Node head)
{
Node slow = head;
Node fast = head;

while(slow && fast && fast.next)
{
  slow = slow.next;
  fast = fast.next.next;

  if(slow == fast)
   return true;
}

return false;
}

Insert into a Cyclic Sorted List

Problem : insert a given value into a sorted circular linked list, given a node in the list
(http://www.leetcode.com/2011/08/insert-into-a-cyclic-sorted-list.html)

Solution:

void insert(Node start, int val)
{
Node tmp = new Node(val);

//if list is empty
if(start == null) { tmp.next = tmp; return; }

//initialize current and greatest pointers
Node current = start;
Node greatest = start;

while(current.next != start)
{
//case 1: node lies between 2 values already present in the list
if(val > current.data && val greatest.data) greatest = current;
}

//now, value is either greater than all values in the list, or smaller than all values. //in any case, value should be inserted after the greatest node
tmp.next = greatest.next;
greatest.next = tmp;

}