Thursday, November 13, 2008

Golden rules for Overriding

This blog entry sums up "all-you-ever-need-to-know" about Overridding Methods in Java. So just follow these simple rules and you will be home. :-)

Golden Rules:
  • The overridden method must have same number and type of arguments(i.e. the same signature) as in the original method of the superclass. Very simple to understand, so go ahead. :-)
  • Methods marked as final or static cannot be overridden. Although, a superclass and subclass can have static methods with same signatures, but that doesn't mean that you have overridden the method of superclass, rather these are inherently separate methods.
  • The overriding method CAN have less restrictive access modifier than the overridden method.
For Example, the following code would compile successfully
>   class base
>   {
>        protected void test()
      {
>          System.out.println(" Base");
>       }
>   }
>  class derived extends base
>  {
>          public void test()
>      {
         System.out.println(" Derived ");
>      }
>  }
  • The overriding method CANNOT have more restrictive access modifier than that of the original method of the superclass.
SuperClass Signature - protected void test(){ ... }
SubClass Signature     - private void test(){ ... }
This won't work. 
  • The overriding method CAN throw any unchecked exception regardless of the overridden method.
> class base
> {
> void hello()
> {
> System.out.println("base");
> }
>  }
> class derived extends base
> {
> void hello() throws RuntimeException
> {
> System.out.println("derived");
> throw new RuntimeException("My Exception from Derived");
> }
> }

  • The overriding method CANNOT throw any broader or new checked exceptions as compared to those thrown by overridden method. However, the overriding method CAN throw any narrower or fewer exceptions.
For Example, this is allowed:
SuperClass Signature - void disp() throws Exception { ... }
SubClass Signature     - void disp() throws RuntimeException { ... }

while this isn't:
SuperClass Signature - void disp() throws ArithmeticException { ... }
SubClass Signature     - void disp() throws RuntimeException { ... }
  • You can override only those methods that you can inherit. So, beware of code which seem to override private methods. 
  • The overridding method return type must be same as that of overridding method or it can be subclass of the original return type. 
> public class overriding
> {
> public static void main(String[] args)
> {
> derived d = new derived();
> derived e = d.print();
> e.print();
> }
> }
> class base
> {
> public base print()
> {
> System.out.println(" Inside Base ");
> return new base();
> }
> }
> class derived extends base
> {
>          @Override
> public derived print()
> {
> System.out.println(" Inside derived ");
> return new derived();
> }
> }

Here, the print() method is overridden though it doesn't look like that. This is known as Covariant-return type and it will work with code written for Java5 platform and above.

For any comments, suggestions or corrections, please leave your comments. :-)

Saturday, November 8, 2008

Many Public Classes in 1 Java File !!

There is a popular misconception among the beginners that we can have multiple public classes in one java source file.
But the rule is that "we can have atmost one public class and any number of non-public classes in one .java source file". The public class must contain the main method, from where the execution begins. As i see it, this is so that JVM could access and call the main method from outside the class. 

However, there is one exception to this rule. I wrote this blog entry because i came to know about the exception :)
The exception comes when we deal with inner classes. You can have as-many-as-you-want public inner classes in your class. But, it is not desirable as it results in difficult-to-manage code and of decreases its re-usability. 

For example, the following code would compile and run successfully.
>
>  class tryme
>  {
>     public static class A
>   {
>   public void print()
>   {   System.out.println(" Print inside A ");   }
>   }
>
>   public static class B
>   {
>   public void display()
>   {   System.out.println(" Display inside B ");   }
>   }
>
>  }
>
>  public class test
>  {
>   public static void main(String[] args)
>   {
>   tryme.A ob = new tryme.A();
>   ob.print();
>
>   tryme.B ob2 = new tryme.B();
>   ob2.display();
>     }
>  }
>

Of course, the file must be named test.java. It compiles and produces the following output.
>
> Print inside A
> Display inside B
>

Another way of using public inner classes is by importing them in your program like
import packagename.tryme.*;
and then use classes A and B as they you like.

But, the recommended style of programming discourages use of more than one public class in one java file. Also, such behaviour is not supported on all compilers. Infact, for maximum optimization (by compiler) it is recommended that you should write one class per java file.

Comments and corrections are welcome. :)

Monday, November 3, 2008

Static Imports in Java

Java as a language, continues to evolve and amaze developers and students alike with new innovative concepts and features. Java 5 is a major release which includes various additions like Generics, Autoboxing, Enumerations, Enhanced for-loop, Static Imports, Var-args, Serialization, Covariant return types, Annotations etc. to name a few.

Discussing each one of them would span multiple blog entries. So let's start with Static Imports as of now. Hopefully, I will devote an entry to each one of these in the coming days. :-)

Before I begin with my explanation of Static Imports, I would like to ask you something..........
Are you sick and tired of using fully-qualified static members of some other class (can be a library class too) in your program such as Math.PI whenever you want to use 3.141592653589793.... or Math.sqrt() when you need to find out square root of any number ??

Of course, these are simple examples which are short and easy to remember, so they might not seem a headache. But things can get quite complex and it can turn out to be burdensome to repeat a long fully-qualified name time and again in your code. 
Static Imports come to your rescue. :-)

With the help of Static imports, you can very well use the static members of any other class (to which you have access) like the members of your class i.e. there is no need to fully qualify the name using package name and class name 

Normally an import statement would look like 
import packageName.className.memberName;

A static import would just add the word "static" after import 
import static packageName.className.memberName;

An example would make it more clear....

>  import static java.lang.Math.*;
>  public class tryme
>  {
>    public static void main(String[] args)
>    {
>      System.out.println("Square root of PI is "+sqrt(PI));
>    }
>  }

The advantage lies in the fact that you dont have to type Math.PI....a simple PI would work....
I agree that its a small feature and not as important as other features that Java 5 has introduced or enhanced, but then as they say "Boond boond se hi gaadha badhta hain"

Limitations :
It applies to only static members, not to instance variables 
It can make code un-readable and difficult to debug, if used unnecessarily and in excess

Application:
Mostly it is used to discourage the technique of declaring constants in interfaces and then implementing those interfaces by your class. An interface is a part of public API and it defines services that your class should provide, and so it is not recommended to make constants a part of your public API. Instead, it is always preferable to use Static Imports.