Core java - Advance Topics
  • Welcome
  • Schedule
  • 1) Exception Handling
    • 1) Introduction to Exception Handling
    • 2) Categories of Exceptions
    • 3) Creating a method that throws an exception
    • 4) Creating Custom Exception Classes
    • 5)What happens when an exception is thrown?
      • 5.1) Creating try-catch-finally blocks
      • 5.2) Using a method that throws a checked exception
      • 5.3) Using a method that throws a runtime exception
      • 5.4) Using a method that throws an error
      • 5.5) Will a finally block execute even if the catch block defines a return statement?
      • 5.6) What happens if both a catch and a finally block define return statement?
      • 5.7) What happens if a finally block modifies the value returned from a catch block?
      • 5.8) Can a try block be followed only by a finally block?
      • 5.9) Does the order of the exceptions caught in the catch blocks matter?
      • 5.10) Can I rethrow an exception or the error I catch?
      • 5.11) Can I declare my methods to throw a checked exception instead of handling it?
      • 5.12) I can create nested loops, so can I create nested try-catch blocks too?
      • 5.13) Should I handle errors?
    • 6) Best Practices
    • 7) Cheat Sheet
    • 8) Problems
  • 2) Wrapper Classes and Enums
    • 2.1) Creating objects of the wrapper classes
    • Enums
  • 3) Inner Classes
    • 3.1) Static nested class (also called static inner class)
    • 3.2) Inner class (also called member class)
    • 3.3) Anonymous inner class
    • 3.4) Method local inner classes
    • CheatSheet
  • 4) Generics
    • Multiple Type parameters in Generic classes
    • Inheritance using Generics
    • Generic interfaces
    • Generic Methods
    • Bounded type parameters
    • Applications
  • 5) Equals and Hashcode
    • Problems
  • CompareTo method overview
  • Basic DS
    • 1) Simple Array List
    • 2) Simple HashMap
  • 5) Collections Framework - Part 1
    • Introducing the collections framework
    • Working with the Collection interface
      • The core Collection interface
      • Methods of the Collection interface
    • Creating and using List, Set, and Deque implementations
      • List interface and its implementations
      • Iterators
      • Sorting List using custom sorting technique
      • Comparable Interface
      • Custom Sorting using comparator
      • ArrayList - Examples and practice problems
    • Stack
    • Linked List
    • LinkedList Operations
  • 6) Collections Framework - Part 2
    • Sets
      • Set Types
      • Array to Set (vice versa)
    • Maps
    • TreeMap
    • Autoboxing And Unboxing
  • Collections Framework - Part 3
    • Basics : DS , Number System
    • Internal Working
      • HashMap
      • HashSet
  • 7) Reflection API
  • 8) Annotations
  • 9) Reading Input From Various Sources
    • File Handling
    • Reading From Xml
    • Reading From JSON
  • 10) Multi-threading (Concurrency)
    • Protect shared data
    • Thread-safe access to shared data
  • 11) Design Patterns
    • Singleton
    • DI
  • 12) Internal Working of JVM
  • 13) Garbage Collection
  • 14) More on Strings (Buffer and Builder)
  • 15) Cloning and Immutable Class
    • 16) Serialization And Deserialization
    • Untitled
  • JAVA 8
    • Interface Changes
    • Lambda
    • Method Ref
    • Optional
    • Streams
    • Predicates
  • Practice Tests
    • Test - Collections
    • OOPS
    • S-OOPS
Powered by GitBook
On this page
  • Default Methods In Java 8
  • Problem :
  • 1)
  • 2)
  • 3)

Was this helpful?

  1. JAVA 8

Interface Changes

Default Methods In Java 8

Before Java 8, interfaces could have only abstract methods. The implementation of these methods has to be provided in a separate class. So, if a new method is to be added in an interface, then its implementation code has to be provided in the class implementing the same interface. To overcome this issue, Java 8 has introduced the concept of default methods which allow the interfaces to have methods with implementation without affecting the classes that implement the interface.

// A simple program to Test Interface default 
// methods in java 
interface TestInterface 
{ 
	// abstract method 
	public void square(int a); 

	// default method 
	default void show() 
	{ 
	System.out.println("Default Method Executed"); 
	} 
} 

class TestClass implements TestInterface 
{ 
	// implementation of square abstract method 
	public void square(int a) 
	{ 
		System.out.println(a*a); 
	} 

	public static void main(String args[]) 
	{ 
		TestClass d = new TestClass(); 
		d.square(4); 

		// default method executed 
		d.show(); 
	} 
} 

Output:

 16
 Default Method Executed

The default methods were introduced to provide backward compatibility so that existing intefaces can use the lambda expressions without implementing the methods in the implementation class. Default methods are also known as defender methods or virtual extension methods.

Static Methods: The interfaces can have static methods as well which is similar to static method of classes.

// A simple Java program to TestClassnstrate static 
// methods in java 
interface TestInterface 
{ 
	// abstract method 
	public void square (int a); 

	// static method 
	static void show() 
	{ 
		System.out.println("Static Method Executed"); 
	} 
} 

class TestClass implements TestInterface 
{ 
	// Implementation of square abstract method 
	public void square (int a) 
	{ 
		System.out.println(a*a); 
	} 

	public static void main(String args[]) 
	{ 
		TestClass d = new TestClass(); 
		d.square(4); 

		// Static method executed 
		TestInterface.show(); 
	} 
} 

Output:

 16
 Static Method Executed

Default Methods and Multiple Inheritance In case both the implemented interfaces contain deafult methods with same method signature, the implementing class should explicitly specify which default method is to be used or it should override the default method.

// A simple Java program to demonstrate multiple 
// inheritance through default methods. 
interface TestInterface1 
{ 
	// default method 
	default void show() 
	{ 
		System.out.println("Default TestInterface1"); 
	} 
} 

interface TestInterface2 
{ 
	// Default method 
	default void show() 
	{ 
		System.out.println("Default TestInterface2"); 
	} 
} 

// Implementation class code 
class TestClass implements TestInterface1, TestInterface2 
{ 
	// Overriding default show method 
	public void show() 
	{ 
		// use super keyword to call the show 
		// method of TestInterface1 interface 
		TestInterface1.super.show(); 

		// use super keyword to call the show 
		// method of TestInterface2 interface 
		TestInterface2.super.show(); 
	} 

	public static void main(String args[]) 
	{ 
		TestClass d = new TestClass(); 
		d.show(); 
	} 
} 

Output:

Default TestInterface1
Default TestInterface2

Important Points:

  1. Interfaces can have default methods with implementation from java 8 onwards.

  2. Interfaces can have static methods as well similar to static method of classes.

  3. Default methods were introduced to provide backward compatibility for old interfaces so that they can have new methods without effecting existing code.

Problem :

Fortunately, rules are available to resolve methods when a derived type inherits method definitions with the same name from different base types. Let us discuss two important scenarios here.

Scenario 1: If two super interfaces define methods with the same signature, the compiler will issue an error. We have to resolve the conflict manually.

//Diamond.java
interface Interface1 {
    default public void foo() { System.out.println("Interface1's foo"); }
}
interface Interface2 {
    default public void foo() { System.out.println("Interface2's foo"); }
}
public class Diamond implements Interface1, Interface2 {
    public static void main(String []args) {
        new Diamond().foo();
    }
}
Error:(9, 8) java: class Diamond inherits unrelated defaults for foo() from types Interface1 and Interface2

In this case, resolve the conflict manually by using the super keyword within the Diamond class to explicitly mention which method definition to use:

public void foo() { Interface1.super.foo(); }

After this method definition is added in the Diamond class and executed, this program prints: Interface1's foo

Scenario 2: If a base class and a base interface define methods with the same signature, the method definition in the class is used and the interface definition is ignored.

class BaseClass {
    public void foo() { System.out.println("BaseClass's foo"); }
}
interface BaseInterface {
    default public void foo() { System.out.println("BaseInterface's foo"); }
}
public class Diamond extends BaseClass implements BaseInterface {
    public static void main(String []args) {
        new Diamond().foo();
    }
}

No compiler error in this case: the compiler resolves to the definition in the class and the interface definition is ignored. This program prints “Base foo”. This can be considered as “class wins” rule. This rule helps maintain compatibility with versions prior to Java 8. How? When a new default method is added in an interface, it may happen to have the same signature as a method defined in a base class. By resolving the conflict by “class wins” rule, the method from the base class will always be selected.

1)


interface Walkable {

	public void walk();

	 default void checkWalkable() {
		System.out.println("Default checkWalkable");
	}

	public static void display() {
		System.out.println("static display");
	}
}

class Human implements Walkable {

	@Override
	public void walk() {
		System.out.println("Human is walking");
	}

	public void checkWalkable() {
		System.out.println("Human checkWalkable");
	}
	
	public  void display() {
		System.out.println("Human static display");
	}
}

public class Problem1 {
	public static void main(String[] args) {
		Walkable.display();
		Walkable walkable = new Human();
		walkable.checkWalkable();
		Walkable.display();
	}
}

2)

interface ParInterface1 {

	public default void method1() {
		System.out.println("method1 from ParInterface1 ");
	}
}

interface ParInterface2 {
	public default void method1() {
		System.out.println("method1 from ParInterface2 ");
	}
}

class Child implements ParInterface1, ParInterface2 {

	@Override
	public void method1() {
		ParInterface1.super.method1();
	}

}

public class Problem2 {
	public static void main(String[] args) {
		ParInterface2 childObj = new Child();
		childObj.method1();
	}
}
 	

3)

interface ParInterface11 {

	public static void method1() {
		System.out.println("method1 from ParInterface11 ");
	}
}

interface ParInterface22 {
	public static void method1() {
		System.out.println("method1 from ParInterface22 ");
	}
}

class Child1 implements ParInterface11, ParInterface22 {
	public static void method1() {
		System.out.println("method1 from Child1 ");
	}
}

public class Problem3 {
	public static void main(String[] args) {
		Child1 childObj = new Child1();
		childObj.method1();
		ParInterface22.method1();
	}
}
PreviousJAVA 8NextLambda

Last updated 5 years ago

Was this helpful?