Tuesday, October 19, 2021

3 Ways to Prevent Method Overriding in Java - Private, Static and Final Method Example Tutorial

Every Java programmer knows that final modifier can be used to prevent method overriding in Java because there is no way someone can override final methods; but, apart from final modifier, is there any other way to prevent method overriding in Java? This was the exact question, asked to one of my friend in a recent Java interview at one of the leading Investment bank. I guess, he was lucky to get this question because he already knows those tricks and was able to answer it quickly. When he told me about his experience,  I didn't understand why someone ask this question? What is the purpose? What they were trying to find out? I can understand if they have asked what's the best way to prevent method overriding in Java, or what is the risk of overriding? 

Anyway, It gives me an opportunity to recap some of the other technique (syntactically) to prevent a method from being overridden and write this blog post to share some mystery tricks from Java world. Some of you might be aware of those non obvious ways to prevent method overriding, but if you don't, here is your opportunity to learn.



Private, Static and Final Methods - Can't Overridden in Java

Apart from final methods there are two more techniques which you can use to prevent a method from being overridden in Java. If you are familiar with private and static modifier in Java, then you may be knowing that private method is not accessible in subclass, which means they can not be overridden as well, because overriding happens at child class.

 Similarly, static methods can not be overridden in Java, because they are resolved and bonded during compile time, while overriding takes place at runtime. They are resolved based upon the type and not object. Overriding happens due to polymorphic property of objects. 

By the way, can you override static methods in Java and why a static method can not be overridden in Java, are also two of the most frequently asked Java questions. In short, apart from final modifier, you can also use static and private modifier to prevent a method from being overridden.




Best Way to Prevent Method Overriding in Java

As far as Java best practice is concerned, you should always use the final keyword to indicate that a method is not meant for overriding. the final modifier has a readability advantage, as well as consistency advantage because as soon as a Java programmer sees a final method, he knows that this can not be overridden. The private method implies that this method is only accessible in this class, which in turns implies that, you can not override private methods on derived class

As you can see, private methods still requires one more step to realize that it can not be overridden. What creates confusion with private and static methods are that, you can hide these methods in subclass. 

There is a difference between method hiding and method overriding, A method is hidden in subclass, if it signature is same as of super class method, but at a call to hidden method is resolved during compile time, while a call to overridden method is resolved during run time.


Difference between final, static and private method

In terms of performance, I think all three private, static and final method performs more or less same, because they all bonded during compile time using static binding. Another reason of using final modifier to prevent method overriding is compile time check. Since an attempt to override a final method is a compilation error in Java, it prevents accidental overriding. 

On the other hand private and static methods can unknowingly hide super class method and create subtle bugs, because compiler will not flag any error or warning. By the way, you can avoid this kind of accidental method overriding by using @Override annotation in Java. 

If you use @Override annotation, whenever you intent to override a method, compiler will flag error and save you from accidentally hiding private and static methods. Just try following Java program after putting @Override annotation on static and private method, to see how compiler helps you.


Code Example - Private, Static, and Final method

In this Java program, we will create two classes Base and Derived with three methods, one static, one final and one private. By observing output, you can see verify that final, private, and static methods can not be overridden in Java

Since overriding final methods is a compilation error, I had to comment on that code. You can clearly see that, even though we have similar private and static methods in the Derived class, and we are using Derived object to call those methods, they are not called. This means the private and static method can only be hidden, but not overridden.

package test;

/**
  * Java program to show that private, static and final method can not be
  * overridden in Java.
  *
  * @author Javin Paul
  */
public class PrivateFinalStaticOverridingTest {
 
    public static void main(String args[]) {
 
        // Reference variable of type Base - Object of type Derived
        Base b = new Derived();
     
        System.out.println(b.version());
        System.out.println(b.name());
           
    }    
 
}

/**
  * Base Class which contains three methods with final, static, and private
  * modifier, to show that these method can't be overridden in Java.
  *
  * @author Javin
  */
class Base{
 
    public final String version(){
        where(); // This will call Base class where() method
        return "1.0.0";
    }
 
    public static String name(){
        return "Base";
    }
 
    private void where(){
        System.out.println("Inside Base Class");
    }
}

/**
  * Derived Class, which extends Base and tries to override final, static
  * and private methods in Java.

  * @author Javin
  */
class Derived extends Base{
 
    // Compilation Error : Final method can't be overridden in Java
//    public final String version(){
//        return "2.0.0";
//    }
 
    // Hidden static method - Same Signature but bonded at compile time
    public static String name(){
        return "Derived";
    }
 
    // Hidden private method - Same signature but resolved at compile time
    private void where(){
        System.out.println("Inside Derived Class");
    }
}

Output:
Inside Base Class
1.0.0
Base

In the code above, you can see that in Base.java we have three methods, final method version(), static method name() and private method where(). In the sub class Derived.java, we tried to override final method but compiler gave us error, forcing us to comment that code. 

Though we are able to create a private and static method of same name and syntax in the sub class, but this is not overriding. To verify that we ran the program and program called methods of derived object with type of base class. 

In this case any overridden method will be execute code defined in derive class but you can see from output that code defined in Base class is executed. In short, its not possible to override private and static method in Java.


That's all about 3 ways to prevent a method from being overridden in Java. Remember, though syntactically you can use private, static and final modifier to prevent method overriding, but you should always use final modifier to prevent overriding. final is best way to say a method is complete and can't be overridden. 


It's also a good coding practice in Java to use @Override annotation, when your intention is overriding and not hiding, this will prevent subtle bugs. You should also be clear, when to use final keyword in Java, because it limits client's ability to override something, but same time necessary to prevent security and sensitive behavior intact.

If you like this article and are interested to read about more interview question discussion, you may like to check out following amazing articles :
  • Why multiple inheritance is not supported in Java? (answer)
  • Why wait(), notify() and notifyAll() must be called from synchronized context? (answer)
  • Can you define final variable without initializing them during declaration? (answer)
  • Can abstract class have constructor in Java? (answer)
  • When to use abstract class over interface in Java? (answer)
  • Does Java is pass by value or pass by reference? (answer)
  • Why use notifyAll() over notify() method in Java? (answer)
  • Why Operator Overloading is not supported in Java? (answer)
  • Why String class is declared final in Java? (answer)
  • Why wait(), notify() and notifyAll() method are defined in Object class and not in Thread? (answer)
  • What is the use of Marker Interface in Java? (answer)
  • How HashSet is internally implemented in Java? (answer)
  • What is the difference between synchronized and concurrent collection in Java? (answer)
  • Can you run Java program without main method? (answer)
  • Why main method is public, static and void in Java? (answer)
  • Why Abstract class is important in Java? (answer)
  • Why character array is better than String for storing password? (answer)
  • Why declaring a no argument constructor is important in Java? (answer)

3 comments:

  1. If you run it this way https://gist.github.com/anonymous/8c5fb0d714d7882b0fef

    you can simulate override of private methods.

    ReplyDelete
  2. It sounds to me the question is wrong - it should say when can't you override a method in Java. Thinking static/private is something you'd use to block overriding as opposed to their intended purposes doesn't sound a good programmer.

    ReplyDelete
  3. your answer is really very nice thank u

    ReplyDelete