[!INDEX]

  1. Interfaces
  2. General Code, animal dog
  3. method without abstract keyword, default public abstract
  4. method with body in interface : wrong way
  5. method with body having default keyword : Code
  6. Why use default keyword
  7. Ambiguity Resolution( multiple method with same name)
  8. Static method + override ( wrong )
  9. Example Use Case of static mt. in interface : as a utility functions
  10. Variable in interface-1
  11. Variable in interface-2
  12. Class inherit interface mt with weaker access modifier

1. Interfaces

[!NOTE]

2. General Code, animal dog

interface Animal {
    void makeSound();
}
class Dog implements Animal {
    public void makeSound() {
        System.out.println("Bark");
    }
}
public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog();
        myDog.makeSound();
    }
}

3. method without abstract keyword, default public abstract

interface I1 {
    void show(); // public abstract void show();
}

[!NOTE] In Java, methods defined in an interface are implicitly abstract and public.


4. method with body in interface : wrong way

interface I1 {
    void show(); // Abstract method
    void display() {
        System.out.println("hi");
    }
} // interface abstract methods cannot have body

5. method with body having default keyword : Code

interface I1 {
    void show(); 
    default void display() { // default method
        System.out.println("hi");
    }
}
class MyClass implements I1 {
    @Override
    public void show() {
        System.out.println("Show method implementation");
    }
    @Override
    public void display(){
        System.out.println("HI");
    }
    public static void main(String[] args) {
        MyClass obj = new MyClass();
        obj.show();    // Calls the implemented method in MyClass
        obj.display(); // Calls the default method in the interface
    }
}

6. Why use default keyword

[!NOTE]

  1. introduced in Java 8 to allow methods in interfaces to have a default implementation.
  2. use to define a method with a default implementation, called default method.
  3. it enable developers to add new methods without breaking the existing implementations of those interfaces.
  4. Default methods must have a body.
  5. Optional for implementing classes.
  6. Inheritance and ambiguity.
  7. Backward Compatibility : One of the primary reasons for introducing default methods was to allow for the evolution of interfaces in a backward-compatible way. Before default methods, adding a new method to an existing interface would break all implementing classes, forcing them to provide an implementation for the new method.
  8. API Evolution : With default methods, library developers can add new methods to interfaces in future releases without breaking existing client code. This allows for more flexible and maintainable API evolution.
  9. Multiple Inheritance of Behavior : Default methods provide a way to achieve multiple inheritance of behavior. This means a class can inherit method implementations from multiple interfaces.

7. Ambiguity Resolution( multiple method with same name)

[!NOTE]

  1. When a class implements multiple interfaces that have default methods with the same signature, the ambiguity must be resolved by overriding the method in the class. For example:
interface I1 {
    default void display() {
        System.out.println("hi from I1");
    }
}
interface I2 {
    default void display() {
        System.out.println("hi from I2");
    }
}
class MyClass implements I1, I2 {
    @Override
    public void display() {
        // Resolve ambiguity, super use for parent memeber access, I1 make it specific
        I1.super.display(); // or I2.super.display();
    }
    public static void main(String[] args) {
        MyClass obj = new MyClass();
        obj.display(); // Calls the overridden method in MyClass
    }
}

8. Static method + override ( wrong )

interface I1 {
    void show(); // Abstract method
    static void display() {
        System.out.println("hi");
    }
}
class MyClass implements I1 {
    @Override
    public void show() { // give error
        System.out.println("Show method implementation");
    }
    public static void main(String[] args) {
        MyClass obj = new MyClass();
        obj.show(); // Calls the implemented method in MyClass   
        // Correct way to call the static method in the interface
        I1.display(); // Outputs: hi
    }
}
//because static methods belong to the interface itself, not the instance of the class.

[!NOTE]

  1. Java 8, interfaces can also have static methods.
  2. Static methods in interfaces can contain a body.
  3. belong to the interface itself .
  4. can call them using the interface name.
  5. cannot be overridden by implementing classes.
  6. not inherited by implementing classes.
  7. called using the interface name.

9. Example Use Case of static mt. in interface : as a utility functions

interface MathOperation {
    double operate(double a, double b);
    static double add(double a, double b) {
        return a + b;
    }
    static double subtract(double a, double b) {
        return a - b;
    }
}
class Addition implements MathOperation {
    @Override
    public double operate(double a, double b) {
        return a + b;
    }
    public static void main(String[] args) {
        Addition addition = new Addition();
        System.out.println("Operation result: " + addition.operate(5, 3)); // Outputs: Operation result: 8.0   
        System.out.println("Static add: " + MathOperation.add(5, 3)); // Outputs: Static add: 8.0
        System.out.println("Static subtract: " + MathOperation.subtract(5, 3)); // Outputs: Static subtract: 2.0
    }
}

[!NOTE]

  1. Static methods in interfaces can be useful for defining utility functions that operate on the types defined by the interface. For example, if you have an interface MathOperation for mathematical operations, you might include static methods for common calculations:

10. Variable in interface-1

interface I1 {
    int a = 10; // Implicitly public static final
    void show();
}
class MyClass implements I1 {
    @Override
    public void show() {
        System.out.println("Show method implementation");
        System.out.println("Value of a: " + a);
    }
    public static void main(String[] args) {
        MyClass obj = new MyClass();
        obj.show(); // Outputs: Show method implementation
                    //          Value of a: 10
    }
}

[!NOTE]

  1. In Java, any variables declared in an interface are implicitly public, static, and final.
  2. This means they are constants that cannot be changed and
  3. are accessible without creating an instance of the interface.

11. Variable in interface-2

interface Constants {
    int MAX_USERS = 100; // public static final
    int MIN_USERS = 1;   // public static final
    void displayLimits();
}
class UserLimits implements Constants {
    @Override
    public void displayLimits() {
        System.out.println("Maximum users: " + MAX_USERS);
        System.out.println("Minimum users: " + MIN_USERS);
    }
    public static void main(String[] args) {
        UserLimits limits = new UserLimits();
        limits.displayLimits(); // Outputs: Maximum users: 100
                                //          Minimum users: 1
    }
}

12. Class inherit interface mt with weaker access modifier

interface I1 { 
    void show(); 
} 
class I12 implements I1{ 
    void show(){// default 
        System.out.println("class i/h i/t m/t"); 
    } 
} // show() in I12 cannot implement show() in I1 // attempting to assign weaker access privileges;