Java prep for 3+ years
Published: 2024-06-18 02:09:00

 1. Tell me the difference between Method Overloading and Method
    Overriding in Java. with example

	Method Overloading:
	Method Overloading refers to defining multiple methods in the same class with the same name but different parameters. The methods can differ in the number of parameters, type of parameters, or both.

	Key Points:

	Method overloading is achieved within the same class.
	It is also known as compile-time polymorphism or static polymorphism.
	The return type may or may not be different, but the parameters must differ in type, sequence, or number.

	```java
	public class OverloadingExample {

	    // Method with the same name but different parameters
	    public int add(int a, int b) {
	        return a + b;
	    }

	    // Overloaded method with different parameter types
	    public double add(double a, double b) {
	        return a + b;
	    }

	    // Overloaded method with different number of parameters
	    public int add(int a, int b, int c) {
	        return a + b + c;
	    }

	    // Overloaded method with different sequence of parameters
	    public int add(int a, double b) {
	        return (int) (a + b);
	    }
	}
	```

	Method Overriding:
	Method Overriding occurs when a subclass provides a specific implementation of a method that is already provided by its superclass. The method in the subclass has the same name, parameter list, and return type as the method in the parent class.

	Key Points:

	Method overriding is achieved between a superclass and its subclass.
	It is also known as runtime polymorphism or dynamic polymorphism.
	The method signatures (name, parameters, return type) must be identical in both the superclass and subclass.

	```java
	// Superclass
	class Animal {
	    public void makeSound() {
	        System.out.println("Animal makes a sound");
	    }
	}

	// Subclass overriding the makeSound() method
	class Dog extends Animal {
	    @Override
	    public void makeSound() {
	        System.out.println("Dog barks");
	    }
	}

	public class Main {
	    public static void main(String[] args) {
	        Animal animal = new Animal();
	        animal.makeSound(); // Output: Animal makes a sound
	        
	        Dog dog = new Dog();
	        dog.makeSound(); // Output: Dog barks
	    }
	}
	```  


2.  What do you mean by the class loader in Java? 

	It seems like you're summarizing the types of built-in class loaders in Java, and you've provided an overview of each type. Let's elaborate on each type of class loader based on your description:

	### 1. Bootstrap Classloader

	- **Description**: The Bootstrap Classloader is the first class loader that initiates when the JVM starts up. It is responsible for loading core Java classes from the bootstrap classpath, which typically includes the `rt.jar` file (or `classes.jar` in older JDK versions). These classes form the Java Standard Edition libraries.
	  
	- **Loaded Classes**: Classes loaded by the Bootstrap Classloader include fundamental Java classes like those in `java.lang`, `java.net`, `java.util`, `java.io`, `java.sql`, etc.

	### 2. Extension Classloader

	- **Description**: The Extension Classloader is the child class loader of the Bootstrap Classloader. It loads classes from the JDK's extension directories (`$JAVA_HOME/jre/lib/ext` by default). These directories contain optional extensions to the standard core Java classes.

	- **Loaded Classes**: Classes loaded by the Extension Classloader typically include classes from JAR files located in `$JAVA_HOME/jre/lib/ext`.

	### 3. System Application Classloader (Application Classloader)

	- **Description**: The System Application Classloader, also known as the Application Classloader, is the child class loader of the Extension Classloader. It loads classes from the application classpath, which is set by the `CLASSPATH` environment variable or specified explicitly using the `-cp` or `-classpath` command-line option.

	- **Loaded Classes**: Classes loaded by the Application Classloader include application-specific classes and third-party libraries that are included in the classpath.

	### Class Loading Hierarchy Summary:

	- **Bootstrap Classloader**: Loads core Java classes (`java.lang`, `java.util`, etc.) from the bootstrap classpath.
	- **Extension Classloader**: Loads classes from extension directories (`$JAVA_HOME/jre/lib/ext`).
	- **Application Classloader**: Loads classes from the application classpath (specified by `CLASSPATH` or `-cp` option).

	### Why Understanding Class Loaders is Important:

	- **Class Loading Flexibility**: Java's class loading mechanism allows applications to dynamically load classes at runtime, enabling features like plugin systems, dynamic class loading, and hot swapping.
	- **Security and Isolation**: Class loaders provide a level of security and isolation, ensuring that classes from different sources (system libraries, extensions, applications) do not interfere with each other.
	- **Customization**: Developers can create custom class loaders to load classes from non-standard sources or apply specific loading policies.

	Overall, understanding the role of each built-in class loader in Java helps developers grasp how classes are loaded and managed within the JVM environment, facilitating effective application development and runtime behavior management.

3. What do you mean by inheritance in Java?

	In Java, inheritance is a mechanism through which an object acquires all the properties and behavior of another class. It is usually used for Method Overriding and Code Reusability.

	The concept of inheritance in Java is based on the fact that it creates new classes that are built upon the existing classes. Therefore, these methods and fields of the parent class can be reused if we inherit from an existing class. And also, we can add new methods and fields to our current class.

	In Java, the inheritance is of five types-

	1. Hybrid Inheritance
	2. Hierarchical Inheritance
	3. Single-level Inheritance
	4. Multi-level Inheritance
	5. Multiple Inheritance

	```java
	// Superclass
	class Animal {
	    // Field
	    protected String name;
	    
	    // Constructor
	    public Animal(String name) {
	        this.name = name;
	    }
	    
	    // Method
	    public void eat() {
	        System.out.println(name + " is eating.");
	    }
	}

	// Subclass inheriting from Animal
	class Dog extends Animal {
	    // Constructor
	    public Dog(String name) {
	        super(name); // Call to superclass constructor
	    }
	    
	    // Additional method specific to Dog
	    public void bark() {
	        System.out.println(name + " is barking.");
	    }
	}

	// Main class to demonstrate inheritance
	public class Main {
	    public static void main(String[] args) {
	        // Create an instance of Dog
	        Dog myDog = new Dog("Buddy");
	        
	        // Access inherited method from Animal
	        myDog.eat(); // Output: Buddy is eating.
	        
	        // Access method specific to Dog
	        myDog.bark(); // Output: Buddy is barking.
	    }
	}
	```
4. Why can we not override the static method in Java?
   
   The reasons why we cannot override the static method in Java are :

(a) The static method does not belong to the object level. Instead, it belongs to the class level. The object decides which method can be called in the method overriding.

(b) In the static method, which is the class level method, the type reference decides on which method is to be called without referring to the object. It concludes that the method that is called is determined at the compile time.

If any child class defines the static method with the same signature as the parent class, then the method in the child class hides the method in the parent class.

```java
class SuperClass {
    public static void staticMethod() {
        System.out.println("Static method in SuperClass");
    }
}

class SubClass extends SuperClass {
    public static void staticMethod() {
        System.out.println("Static method in SubClass");
    }
}

public class Main {
    public static void main(String[] args) {
        SuperClass.staticMethod(); // Output: Static method in SuperClass
        SubClass.staticMethod();   // Output: Static method in SubClass
    }
}
```

5. Can you tell us what the Dynamic Method Dispatch is in Java?

Dynamic Method Dispatch in Java refers to the mechanism by which the correct method implementation is determined at runtime, based on the object type rather than the reference type. It enables polymorphic behavior in Java, allowing a subclass to provide a specific implementation of an inherited method.

```java
class Animal {
    public void makeSound() {
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Dog barks");
    }
}

class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Cat meows");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal1 = new Dog(); // Dog object
        Animal animal2 = new Cat(); // Cat object
        
        animal1.makeSound(); // Output: Dog barks
        animal2.makeSound(); // Output: Cat meows
    }
}
```