Adding new methods in interfaces always break the implementation in class. So Java 8 come up with new feature which propose a mechanism to extend existing interfaces by adding new methods without breaking existing implementation thus, achieved the backward compatibility.
Default methods is the feature which helps you to extend existing interfaces.
If added method in interface provides the default implementation then no implementing Class get affects.
Default methods enable you to add new functionality to the interfaces of your libraries and ensure binary compatibility with code written for older version of those interfaces.
Default methods enable you to add new functionality to the interfaces of your libraries and ensure binary compatibility with code written for older version of those interfaces.
An implementing class can override the default implementation defined in implemented interface and add its own implementation.
To understand it with example, lets say there is ABC company which wants to launch their smart Radios in market, so they have developed SmartRadio interface(contract) and ABCRadio final product implements all the functionality specified by SmartRadio.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* SmartRadio enough smart which let you tune your favorite channel in louder and lower volumes | |
*/ | |
public interface SmartRadio { | |
//old declared methods | |
public void tuneChannel(float channelFrequency); | |
//old declared methods | |
public void increaseVolume(); | |
//old declared methods | |
public void decreaseVolume(); | |
} | |
/** | |
* ABC company has launched their {@link ABCRadio} which type of SmartRadio | |
*/ | |
public class ABCRadio implements SmartRadio { | |
private final int MAX_VOLUME_LEVEL = 100; | |
private final int MIN_VOLUME_LEVEL = 0; | |
private int volumeLevel; | |
public ABCRadio() { | |
volumeLevel = 10; | |
} | |
@Override | |
public void tuneChannel(float channelFrequency) { | |
System.out.println("Channel tuned to :" + channelFrequency); | |
} | |
@Override | |
public void increaseVolume() { | |
if (volumeLevel <= MAX_VOLUME_LEVEL) | |
volumeLevel += 10; | |
System.out.println("volume adjusted to: " + volumeLevel); | |
} | |
@Override | |
public void decreaseVolume() { | |
if (volumeLevel >= MIN_VOLUME_LEVEL) | |
volumeLevel -= 10; | |
System.out.println("volume adjusted to: " + volumeLevel); | |
} | |
} |
Later, ABC company decided to launch next generation radio in which they do not want their radio listeners to remember and provide channel frequency manually so the company decided o automate this via autotune feature which let user to tune channel automatically without asking for particular channel frequency.
Job was not that easy because they want to extend the SmartRadio contract without effecting their already launched ABCRadio in market, so to rescue them default methods has arrived.
see below code with added default method in SmartRadio interface.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* SmartRadio enough smart which let you tune your | |
* favorite channel in louder and lower volumes | |
* Now added smartness of auto tuning channel | |
*/ | |
public interface SmartRadio { | |
//old declared methods | |
public void tuneChannel(float channelFrequency); | |
//old declared methods | |
public void increaseVolume(); | |
//old declared methods | |
public void decreaseVolume(); | |
//new method added | |
default public void autoTuneChannel() { | |
System.out.println("auto tune channel feature added"); | |
} | |
} | |
/** | |
* ABC company has now launched their next smart {@link ABCAutoTuneRadio} | |
* which is type of SmartRadio but with added auto tune feature. | |
*/ | |
public class ABCAutoTuneRadio extends ABCRadio { | |
final float MIN_FREQ = 85.00F; | |
final float MAX_FREQ = 110.00F; | |
@Override | |
public void autoTuneChannel() { | |
for (float startFreq = MIN_FREQ; startFreq <= MAX_FREQ; startFreq += 1.0) { | |
tuneChannel(startFreq); | |
if (channel.isTuned()) { | |
break; | |
} | |
} | |
System.out.println("channel auto tuned to : " + getFrequency()); | |
} | |
} |
so default methods is one of nice feature in Java 8, you can have as much as possible default methods in your interfaces and optional to override in your class without breaking already written classes.
As you all know Java don't allow to extend multiple classes to avoid diamond problem but allows to implement multiple interfaces, so what if more than one interfaces has same default methods signature and any class implements all these such interfaces then?
if such scenario happened then java compiler wont let you compile your code by saying unrelated defaults noticed from such such interfaces and forces you to override the method in implementing class.
see below code for more explanation:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class DefaultMethodAmbiguity { | |
interface A{ | |
default public void a(){ | |
System.out.println("Default method in inteface A"); | |
} | |
} | |
interface B{ | |
default public void a(){ | |
System.out.println("Default method in inteface B"); | |
} | |
} | |
class AB implements A,B{ | |
@Override | |
public void a() { | |
System.out.println("Override method a()"); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class DefaultMethodAmbiguity { | |
interface A { | |
default public void a() { | |
System.out.println("Default method in inteface A"); | |
} | |
} | |
interface B { | |
default public void a() { | |
System.out.println("Default method in inteface B"); | |
} | |
} | |
class AB implements A, B { | |
@Override | |
public void a() { | |
System.out.println("Override method a()"); | |
//calling default method a() from interface A | |
A.super.a(); | |
//calling default method a() from interface B | |
B.super.a(); | |
} | |
} | |
} |
Two different interfaces can not have same default method defined with only difference of return type in that case you will be confusing java compiler and it wont let you compile your code.
Comments
Post a Comment