Sunday, April 23, 2023

Difference in Method Overloading, Overriding, Hiding, Shadowing and Obscuring in Java and Object-Oriented Programming?

Hello guys, today, I am going to explain a couple of fundamental object-oriented programming concepts in Java, like Overloading, Overriding, Hiding, Shadowing, and Obscuring. The first two are used in the context of a method in Java while the last three are used in the context of variables in Java. Two methods with the same name and same class but the different signature is known as overloading and the method is known as an overloaded method while a method with the same name and same signature but in parent and child class is known as overriding. On the other hand,  Hiding is related to overriding since the static and private method cannot be overridden, if you declare such methods with the same name and signature in parent and child class then the method in the child class will hide the method in the parent class.

I'll explain this in more detail with the example but for now, you can assume that a static method with the same name and signature in parent and child class is known as method hiding. Even a field can be hidden if you declare another field with the same name in a subclass.

Shadowing of variable occurs when a local variable uses the same name as previously declared member variable. Since the local variable gets preference in a local block of code, they shadow member variables like instance and class variables.

Obscuring is rather a rare situation when you declare a variable with the same name as Class and the precedence rule may renter the class unusable. In practice, this will never occur if you follow Java's Class and variables naming convention because the Class name always starts with a capital letter while the variable starts with a small letter.

Btw, if you are not familiar with Java's variable naming convention I suggest you first go through an in-depth Java course like The Complete Java Masterclass on Udemy. It's also the most up-to-date course and covers recent Java versions like Java 9, Java 16, etc.

Now that we know what does overloading, overriding, hiding, shadowing, and obscuring mean in Java, let's understand them in more detail with simple examples.





1. Method Overloading

This is an important but confusing concept in Java. Two methods with the same name in the same class but the different signature is said to be overloaded methods. One of the popular examples is the println() method in the PrintStream class which is overloaded to accept an int, long, String, boolean, and other data types.

Here is an example of overloading in Java

public class Code {

  public void show(String message) {
    System.out.println("String: " + message);
  }

  public void show(int content) {
    System.out.println("int: " + content);
  }
}


In this example, the method show() is overloaded because there is two show method in the Code class. The method signature which is made of the number, type, and order of argument is different for both of these methods. This is the primary requirement for overloading.

Overloading is normally used to declare methods whose function is the same as printing messages in our example but they work with different types of arguments. 

They are also resolved at compile time. If you want to learn more about method overriding in Java I suggest you go through an OOP course on Java, like Learn Object-Oriented Programming in Java on Educative, a new learning platform that focuses on interactive learning.

Difference between Overloading, Overriding, Hiding, Shadowing and Obscuring in Java and OOP


2. Method Overriding

Overriding is the opposite of Overloading. In this case, we have methods with the same name and same signature but in parent and child classes. The method in the child class is known as an overriding method while the method in the parent class is referred to as an overridden method. Unlike Overloading, this is resolved at runtime, depending upon the type of object which is calling the method.

Here is an example of overriding a method in Java:

class Parent {

  public void watch() {
    System.out.println("Parent watching movies");
  }
}

class Child extends Parent {

  @Override
  public void watch() {
    System.out.println("Child watching Cartoons ");
  }
}

public class Code {

  public static void main(String[] args) {
    Parent p = new Parent();
    Parent c = new Child();
    p.watch();
    c.watch();
  }
}

Output:
Parent watching movies
Child watching Cartoons

You can see that when p.watch() is called the watch() method from the Parent class is called but on the next line even though the variable type was still Parent, the c.watch invokes watch() method from Child class because this time object was of Child class and watch() method was overridden in Child class

And, if you are still not sure about the difference between Overloading and Overriding, then here is a diagram that explains better than me. It's said that a picture is worth 1000 words and this diagram just proves it. Awesome.



3. Hiding

You can hide a field or variable in Java. A field is said to be hidden by another field if they have the same name in both parent and child classes. For example, if Parent class has a name field and Child class also has an age field then Child.age will hide Parent.age in the Child class.

If you use age then it will always refer to the name field from Child class rather than the Parent class as shown in the following example:

class Parent {
  int age = 30;
}

class Child extends Parent {
  int age = 4;

  public void age() {
    System.out.println("just age: " + age);
    System.out.println("Parent's age: " + super.age);
    System.out.println("Child's age: " + this.age);
  }
}

public class Code {

  public static void main(String[] args) {
    Child c = new Child();
    c.age();

  }
}

Output:
just age: 4
Parent's age: 30
Child's age: 4

You can see that if you refer to the age field, the value from Child.age is printed, which means it hides the Parent.age field.  Though you can access the superclass value by using a super keyword as shown in the above example. Similarly, by using this keyword you can enforce that value from the current Class is used, in our case Child class.

If you are not familiar with this and super keyword in Java, I suggest you join a comprehensive course like The Complete Java Masterclass to learn fundamentals betters. It's also one of the most up-to-date courses and recently updated to cover the latest Java version.



As I said, you cannot only hide variables in Java but also the method can also be hidden. For example, if you have two static methods with the same name in both Parent and Child class then the method in Child class will hide the method from the Parent class.

Here is an example of a method hiding in Java:

class Parent {

  public static String info() {
    return "Born in 1970";
  }

}

class Child extends Parent {

  public static String info() {
    return "Born in 2018";
  }

  public void show() {
    System.out.println("info : " + info());
    System.out.println("Parent's info : " + Parent.info());
    System.out.println("Child's info : " + Child.info());
  }
}

public class Code {

  public static void main(String[] args) {
    Child c = new Child();
    c.show();

  }
}

Output
info: Born in 2018
Parent's info: Born in 1970
Child's info: Born in 2018

You can see that when we just called the info() method in a subclass, the method from the Child class is called, it means it has hidden the info() method from the Parent class.

Though, you can access the hidden method of Parent class either by using Classname like Parent.info() or super keyword e.g. super.info()

Similarly, you can call the method from the same class using this.info() or Child.info() because the info is a static method. If you are not familiar with concepts of static variables and methods, you should join an in-depth Java course like Java Fundamentals: The Java Language on Pluralsight.

Difference between Overloading, Overriding,



4. Shadowing

One variable can shadow another variable in Java if they have the same name. For example, if you a field called age and a local variable also called "age" then the local variable will shadow the field because, in a local block, the local variable has higher precedence than a member variable or field.

Here is an example of shadowing a variable in Java:


class Parent {

}

class Child extends Parent{
private int age = 1;

public void show(){
int age = 5;
System.out.println("age: " + age);
System.out.println("age field value: " + this.age);
}
}

public class Code{

public static void main(String[] args){
Child c = new Child();
c.show();

}
}

Output:
age: 5
age field value: 1

You can see that age is printed as "5" rather than 1 because the local variable age defined inside the show() method has shadowed the age field. If you want to access the field then you can always do so by using this modifier as shown in the above example. You can also see Learn Object-Oriented Programming in Java course on Educative to learn more about other OOP concepts in Java.





5. Obscuring

This is another problem that arises due to sharing the same name for a variable and a class in Java. For example, if a local variable has the same name as a Class then the precedence rules may render the class unusable. In this case, the class is said to be obscured by the variable.

Here is an example of obscuring in Java:


public class Code{

 public static void main(String[] args){

  String System = "Obscuring";
  System.out.println(System);

  }
}

This program will not compile because Java will think that the System is a local variable and out cannot be resolved. In Eclipse it throws a compile-time error with "out cannot be resolved or is not a field".

The good thing about this is that it will never occur if you stick with Java's naming for class and variables. In Java, the name of the class starts with a capital letter while the name of the variable starts with a small letter, which means even if the two start with the same letter they will never obscure each other.


That's all about the difference between Overloading, Overriding, Hiding, Shadowing, and Obscuring variables and methods in Java. I know, they are quite confusing sometimes but once you understand their true meaning and the example given in this article, you can easily recognize them in code.

Other Java and Programming Resources you may like
  • The Java Developer RoadMap (guide)
  • 10 Things Java Programmer should learn (things)
  • 5 Free Courses to learn Object Oriented Programming (courses)
  • 10 Books Every Programmer Must Read (books)
  • 10 Courses to learn DevOps in Depth (courses)
  • 10 Tips to Improve Your Programming skill (tips)
  • 7 Best courses to learn design patterns in Java (courses)
  • 10 Tools Every Software Developer should know (tools)
  • 5 Courses to Learn Software Architecture in Depth (courses)
  • 20 Libraries and APIS Java Programmer Should Know (libraries)
  • Top 10 Programming languages to Learn (languages)
  • 10 Articles Every Programmer Should Read (articles)
  • 10 Framework and Library Java and Web Developer Should Learn (frameworks)
  • 75 Programming interview Questions for Programmers (Questions)
  • 30 OOP Interview questions with answers (questions)

Thanks for reading this article so far. If you find this article useful and able to understand essential OOP concepts like overloading, overriding, hiding, shadowing, and obscuring them please share with your friends and colleagues on Facebook, Twitter, or Linkedin. If you have any questions or doubt then please drop a note.

P. S. - If you are new to the Java Programming world and want to learn Java but looking for a free course then you can also check out this list of 10 Free Java Programming courses for beginners and anyone who wants to learn Java. 

No comments:

Post a Comment

Feel free to comment, ask questions if you have any doubt.