Friday, 19 April 2013

Abstract classes and functions in java

Abstract classes are the basis for what is yet to come - interfaces. So lets understand what are abstract classes and why are these important.

In the tutorial on polymorphism we saw how reference of type Animal can be used to point at object of various types like Cat,Dog,Lion,Wolf,Hippo etc. 
 
Just to revise things we now know we can say -

Wolf aWolf = new Wolf();


or we can also say -

Animal aHippo = new Hippo (); 


 but what happens when we do -

Animal animal = new Animal();

Perfectly Valid Java syntax. But what does this Animal look like?

This only makes sense when we have some concrete Animal like Dog,Cat etc . In short it does not make any sense to create objects of class Animal or in other words it does not  make any sense to use new() operator with Animal class. In this case we declare the class as abstract. Such abstract classes are used in polymorphism.

Syntax for making abstract classes
abstract public class Animal

Note: Though we cannot create objects of abstract classes we can use them as reference (like in Polymorphism).

Also remember you cannot use functions of subclass through super class reference(polymorphism) unless the function is defined in the super class. But also we cannot implement the function in the super class as the implementation will be subclass specific( eg different implementation for Dog,Cat etc). To sum thing up, for using polymorphism effectively we need function declared in super class and it's concrete implementation in the subclass. Hence we define the functions to be abstract.

Syntax for abstract function -
abstract returnType functionName(Arguments);

Note : No Method body. No brace brackets. Just a semicolon after method declaration. 


 Observe the semi colon after function prototype.  We just declare it and put a semi colon after it. Implementation of this function will be in the first concrete class which implements this abstract class. There is no use of abstract class if no class implement it(i.e if there are no subclasses of abstract class).

Note: There can be non-abstract functions in abstract classes but there can never be abstract functions in a non-abstract class. So if you have abstract functions you must declare your class to be abstract.

Also note there is no such thing as abstract variables. In java we just have abstract classes and abstract function.

Few points to note

  1. A non abstract class cannot have abstract method. If a class has abstract method it has to be made abstract.
  2. We cannot instantiate abstract classes.
  3. An abstract class can have non abstract methods .
  4. If your abstract class has all abstract method it is better to go for an interface instead.









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 - 


t> UA-39527780-1 back to top