Java Interface Example
In this post, we feature a comprehensive Java Interface Example.
You can also check this tutorial in the following video:
1. Introduction
Java interface is an abstract type that defines methods that classes must implement. It can contain constants, abstract method signatures, default methods along with an implementation body, static methods along with an implementation body, and nested types. Java Interface defines the “contracts” and represents the IS-A relationship. Interface design pattern is one of the best known patterns in software engineering.
Java defines lots of interfaces. Interface List is a well-known example. Java implements it with several implementation classes: AbstractList, AbstractSequentialList, ArrayList, AttributeList, CopyOnWriteArrayList, LinkedList, RoleList, RoleUnresolvedList, Stack, Vector.
In this example, I will create a maven project to demonstrate the following interface features:
- Defining an
interfacewhich contains default, static, private, and abstract methods - Defining an
interfacewhich extends from one or moreinterfaces - Creating an implementation class from a single
interface - Creating an implementation class from multiple interfaces
- Utilizing the
interfacedesign pattern in an application
2. Technologies Used
The example code in this example was built and run with:
- Java 11
- Maven 3.3
- Eclipse
- Junit 4.12
- Logback
3. Maven Project
3.1 Dependencies
I will include both Junit and Logback in the pom.xml.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>jcg-zheng-interface-demo</groupId> <artifactId>jcg-zheng-interface-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <build> <sourceDirectory>src</sourceDirectory> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <release>11</release> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-access</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.2.3</version> </dependency> </dependencies> </project>
4. Interfaces
In this step, I will created five interfaces based on the following diagram.

4.1 MusicalInstrument
In this step, I will create a MusicalInstrument interface which contains:
static String PLAY_MSG– a constant string value of ” plays “private static boolean isBroke()– a private method which returns a true or false valuepublic static String repair()– a public static method which repairs a musical instrument.default String demo()– a default method which returns a messageString instrumentName()– a public abstract method which every implementation class must implementvoid play(String song)– a public abstract method which every implementation class must implementprivate String playMsg()– a private method which returns aStringvalue
MusicalInstrument.java
package jcg.zheng.demo.api;
import java.util.Random;
/**
*
* Interface defines "contracts"
*
* JDK 8
*
* 1) add Default interface method to preserve backward compatibility when
* modifying an interface by adding new methods when the interface has more than
* one implementations. Adding new methods will force all the implementation to
* implement these new methods. With Default interface method solve this issue.
* 2) add static method
*
* JDK 9 add private method
*
*/
public interface MusicalInstrument {
static String PLAY_MSG = " plays : ";
private static boolean isBroke() {
boolean isBroke = false;
Random ran = new Random();
int nxt = ran.nextInt();
if (nxt % 8 == 0) {
isBroke = true;
}
return isBroke;
}
/**
* repair the instrument
*
* @param isBroke
* @return a message show the repair result;
*/
public static String repair() {
if (isBroke()) {
return "Fixed";
}
return "In good condition";
}
/**
* Play demo song
*
* @return
*/
default String demo() {
return instrumentName() + playMsg();
}
/**
* Return the musical instrument name
*
* @return the musical instrument name
*/
String instrumentName();
/**
* Play the given song
*
* @param song the song to play
*/
void play(String song);
private String playMsg() {
return " plays a demo song";
}
}
4.2 BrassInstrument
In this step, I will create a BrassInstrument interface which extends from MusicalInstrument with an additional buzz(String song) method.
BrassInstrument.java
package jcg.zheng.demo.api;
public interface BrassInstrument extends MusicalInstrument {
/**
* Make a buzz sound for the given song
*
* @param song the given song
*/
void buzz(String song);
}
4.3 StringInstrument
In this step, I will create a StringInstrument interface which extends from MusicalInstrument along with two additional methods: bow(String song) and pluck(String song).
StringInstrument.java
package jcg.zheng.demo.api;
public interface StringInstrument extends MusicalInstrument {
/**
* Play the song with a bow
*
* @param song
*/
void bow(String song);
/**
* Play the song by plucking
*
* @param song
*/
void pluck(String song);
}
4.4 ChildrenToy
In this step, I will create a ChildrenToy interface which has one default method – demo .
ChildrenToy.java
package jcg.zheng.demo.api;
public interface ChildrenToy {
/**
* Play the demo song
*
* @return the demo song
*/
default String demo() {
return "Play the demo song";
}
}
4.5 PercussionInstrument
In this step, I will create a PercussionInstrument interface which extends from both MusicalInstrument and ChildrenToy interfaces. I will override the demo method because both parent interfaces have the demo method.
PercussionInstrument.java
package jcg.zheng.demo.api;
public interface PercussionInstrument extends MusicalInstrument, ChildrenToy {
/**
* use the MusicalInstrument demo sine both interface has demo
*/
@Override
default String demo() {
return MusicalInstrument.super.demo();
}
/**
* Play the song by hitting
*
* @param song
*/
void hit(String song);
/**
* Play the song by shaking
*
* @param song
*/
void shake(String song);
}
5. Implementation Classes
In this step, I will create nine implementation classes base on the following diagram.

5.1 Bell
In this step, I will create a Bell class which implements the PercussionInstrument interface.
Bell.java
package jcg.zheng.demo.api.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jcg.zheng.demo.api.PercussionInstrument;
public class Bell implements PercussionInstrument {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void hit(String song) {
logger.info(instrumentName() + PLAY_MSG + song);
}
@Override
public String instrumentName() {
return "Bell";
}
@Override
public void play(String song) {
shake(song);
}
@Override
public void shake(String song) {
logger.info(instrumentName() + PLAY_MSG + song);
}
}
5.2 Drum
In this step, I will create a Drum class which implements the PercussionInstrument interface.
Drum.java
package jcg.zheng.demo.api.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jcg.zheng.demo.api.PercussionInstrument;
public class Drum implements PercussionInstrument {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void hit(String song) {
logger.info(instrumentName() + PLAY_MSG + song);
}
@Override
public String instrumentName() {
return "Drum";
}
@Override
public void play(String song) {
hit(song);
}
@Override
public void shake(String song) {
throw new UnsupportedOperationException();
}
}5.3 KidDrumToy
In this step, I will create a KidDrumToy class which implements the PercussionInstrument interface.
KidDrumToy.java
package jcg.zheng.demo.api.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jcg.zheng.demo.api.PercussionInstrument;
public class KidDrumToy implements PercussionInstrument {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public String demo() {
return "KidDrumToy play the demo song by hitting and shaking";
}
@Override
public void hit(String song) {
logger.info(instrumentName() + PLAY_MSG + song + " when is hit.");
}
@Override
public String instrumentName() {
return "KidMusicToy";
}
@Override
public void play(String song) {
hit(song);
shake(song);
}
@Override
public void shake(String song) {
logger.info(instrumentName() + PLAY_MSG + song + " when is shaked.");
}
}5.4 KidMusicalToy
In this step, I will create a KidMusicalToy class which implements both PercussionInstrument and StringInstrument interfaces.
KidMusicalToy.java
package jcg.zheng.demo.api.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jcg.zheng.demo.api.BrassInstrument;
import jcg.zheng.demo.api.StringInstrument;
public class KidMusicalToy implements BrassInstrument, StringInstrument {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void bow(String song) {
logger.info("play a string with a bow " + song);
}
@Override
public void buzz(String song) {
logger.info("make a buzz sound " + song);
}
@Override
public String demo() {
return "KidMusicToy play the demo song with String and buzz";
}
@Override
public String instrumentName() {
return "KidMusicToy";
}
@Override
public void play(String song) {
bow(song);
pluck(song);
buzz(song);
}
@Override
public void pluck(String song) {
logger.info("play a string with a pluck sound " + song);
}
}5.5 Trumpet
In this step, I will create a Trumpet class which implements the BrassInstrument interface.
Trumpet.java
package jcg.zheng.demo.api.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jcg.zheng.demo.api.BrassInstrument;
public class Trumpet implements BrassInstrument {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void buzz(String song) {
logger.info(instrumentName() + PLAY_MSG + song);
}
@Override
public String instrumentName() {
return "Trumpet";
}
@Override
public void play(String song) {
buzz(song);
}
}5.6 Tuba
In this step, I will create a Tuba class which implements the BrassInstrument interface.
Tuba.java
package jcg.zheng.demo.api.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jcg.zheng.demo.api.BrassInstrument;
public class Tuba implements BrassInstrument {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void buzz(String song) {
logger.info(instrumentName() + PLAY_MSG + song);
}
@Override
public String demo() {
return "Tuba overrides the default demo method";
}
@Override
public String instrumentName() {
return "Tuba";
}
@Override
public void play(String song) {
buzz(song);
}
}5.7 Viola
In this step, I will create a Viola class which implements the StringInstrument interface.
Viola.java
package jcg.zheng.demo.api.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jcg.zheng.demo.api.StringInstrument;
public class Viola implements StringInstrument {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void bow(String song) {
logger.info(instrumentName() + PLAY_MSG + song);
}
@Override
public String instrumentName() {
return "Viola";
}
@Override
public void play(String song) {
bow(song);
}
@Override
public void pluck(String song) {
throw new UnsupportedOperationException();
}
}5.8 Violin
In this step, I will create a Violin class which implements the StringInstrument interface.
Violin.java
package jcg.zheng.demo.api.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jcg.zheng.demo.api.StringInstrument;
public class Violin implements StringInstrument {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void bow(String song) {
logger.info(instrumentName() + PLAY_MSG + song);
}
@Override
public String instrumentName() {
return "Violin";
}
@Override
public void play(String song) {
bow(song);
}
@Override
public void pluck(String song) {
throw new UnsupportedOperationException();
}
}5.9 Violin2
In this step, I will create a Violin2 class which implements the StringInstrument interface.
Violin2.java
package jcg.zheng.demo.api.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jcg.zheng.demo.api.StringInstrument;
public class Violin2 implements StringInstrument {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void bow(String song) {
logger.info(instrumentName() + PLAY_MSG + song);
}
@Override
public String instrumentName() {
return "Violin2";
}
@Override
public void play(String song) {
bow(song);
}
@Override
public void pluck(String song) {
throw new UnsupportedOperationException();
}
}6. Junit Tests
6.1 AbstractionTest
In this step, I will create an AbstractionTest class which has a list of MusicalInstruments and invokes its default demo method and abstract play method. I will use the logger to print out the messages.
AbstractionTest.java
package jcg.zheng.demo.api.impl;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import jcg.zheng.demo.api.MusicalInstrument;
public class AbstractionTest {
List<MusicalInstrument> musicInstruments = new ArrayList<>();
@Test
public void polymorphism_with_abstract_method() {
musicInstruments.forEach(mi -> mi.play("Hello"));
}
@Test
public void polymorphism_with_default_method() {
musicInstruments.forEach(mi -> System.out.println(mi.demo()));
}
@Before
public void setupBand() {
musicInstruments.add(new Violin());
musicInstruments.add(new Viola());
musicInstruments.add(new Bell());
musicInstruments.add(new Drum());
musicInstruments.add(new Trumpet());
musicInstruments.add(new Tuba());
musicInstruments.add(new KidMusicalToy());
musicInstruments.add(new KidDrumToy());
musicInstruments.add(new Violin2());
}
}
Execute mvn test -Dtest=AbstractionTest command and capture the output here.
Output
C:\MaryZheng\Workspaces\jdk12\jcg-zheng-interface-demo>mvn test -Dtest=AbstractionTest [INFO] Scanning for projects... [INFO] [INFO] ---------< jcg-zheng-interface-demo:jcg-zheng-interface-demo >---------- [INFO] Building jcg-zheng-interface-demo 0.0.1-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ jcg-zheng-interface-demo --- [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory C:\MaryZheng\Workspaces\jdk12\jcg-zheng-interface-demo\src\main\resources [INFO] [INFO] --- maven-compiler-plugin:3.8.0:compile (default-compile) @ jcg-zheng-interface-demo --- [INFO] Changes detected - recompiling the module! [WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. build is platform dependent! [INFO] Compiling 17 source files to C:\MaryZheng\Workspaces\jdk12\jcg-zheng-interface-demo\target\classes [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ jcg-zheng-interface-demo --- [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory C:\MaryZheng\Workspaces\jdk12\jcg-zheng-interface-demo\src\test\resources [INFO] [INFO] --- maven-compiler-plugin:3.8.0:testCompile (default-testCompile) @ jcg-zheng-interface-demo --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ jcg-zheng-interface-demo --- [INFO] Surefire report directory: C:\MaryZheng\Workspaces\jdk12\jcg-zheng-interface-demo\target\surefire-reports ------------------------------------------------------- T E S T S ------------------------------------------------------- Running jcg.zheng.demo.api.impl.AbstractionTest Violin plays a demo song Viola plays a demo song Bell plays a demo song Drum plays a demo song Trumpet plays a demo song Tuba overrides the default demo method KidMusicToy play the demo song with String and buzz KidDrumToy play the demo song by hitting and shaking Violin2 plays a demo song 21:34:55.464 [main] INFO jcg.zheng.demo.api.impl.Violin - Violin plays : Hello 21:34:55.472 [main] INFO jcg.zheng.demo.api.impl.Viola - Viola plays : Hello 21:34:55.473 [main] INFO jcg.zheng.demo.api.impl.Bell - Bell plays : Hello 21:34:55.476 [main] INFO jcg.zheng.demo.api.impl.Drum - Drum plays : Hello 21:34:55.478 [main] INFO jcg.zheng.demo.api.impl.Trumpet - Trumpet plays : Hello 21:34:55.482 [main] INFO jcg.zheng.demo.api.impl.Tuba - Tuba plays : Hello 21:34:55.497 [main] INFO jcg.zheng.demo.api.impl.KidMusicalToy - play a string with a bow Hello 21:34:55.498 [main] INFO jcg.zheng.demo.api.impl.KidMusicalToy - play a string with a pluck sound Hello 21:34:55.499 [main] INFO jcg.zheng.demo.api.impl.KidMusicalToy - make a buzz sound Hello 21:34:55.516 [main] INFO jcg.zheng.demo.api.impl.KidDrumToy - KidMusicToy plays : Hello when is hit. 21:34:55.517 [main] INFO jcg.zheng.demo.api.impl.KidDrumToy - KidMusicToy plays : Hello when is shaked. 21:34:55.519 [main] INFO jcg.zheng.demo.api.impl.Violin2 - Violin2 plays : Hello Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.577 sec Results : Tests run: 2, Failures: 0, Errors: 0, Skipped: 0 [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 9.610 s [INFO] Finished at: 2019-06-25T21:34:55-05:00 [INFO] ------------------------------------------------------------------------
6.2 RuntimeTest
In this step, I will create a RuntimeTest class which will create a different Violin class based on the condition.
RuntimeTest.java
package jcg.zheng.demo.api.impl;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import jcg.zheng.demo.api.MusicalInstrument;
public class RuntimeTest {
@Test
public void runtime_injection() {
MusicalInstrument violin = violinBuilder(false);
assertEquals(Violin.class, violin.getClass());
}
@Test
public void runtime_injection_2() {
MusicalInstrument violin = violinBuilder(true);
assertEquals(Violin2.class, violin.getClass());
}
private MusicalInstrument violinBuilder(boolean isVersion2) {
MusicalInstrument violin;
if (isVersion2) {
violin = new Violin2();
} else {
violin = new Violin();
}
return violin;
}
}
Execute mvn test -Dtest=RuntimeTest command and capture the output here.
Output
C:\MaryZheng\Workspaces\jdk12\jcg-zheng-interface-demo>mvn test -Dtest=RuntimeTest [INFO] Scanning for projects... [INFO] [INFO] ---------< jcg-zheng-interface-demo:jcg-zheng-interface-demo >---------- [INFO] Building jcg-zheng-interface-demo 0.0.1-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ jcg-zheng-interface-demo --- [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory C:\MaryZheng\Workspaces\jdk12\jcg-zheng-interface-demo\src\main\resources [INFO] [INFO] --- maven-compiler-plugin:3.8.0:compile (default-compile) @ jcg-zheng-interface-demo --- [INFO] Changes detected - recompiling the module! [WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. build is platform dependent! [INFO] Compiling 17 source files to C:\MaryZheng\Workspaces\jdk12\jcg-zheng-interface-demo\target\classes [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ jcg-zheng-interface-demo --- [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory C:\MaryZheng\Workspaces\jdk12\jcg-zheng-interface-demo\src\test\resources [INFO] [INFO] --- maven-compiler-plugin:3.8.0:testCompile (default-testCompile) @ jcg-zheng-interface-demo --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ jcg-zheng-interface-demo --- [INFO] Surefire report directory: C:\MaryZheng\Workspaces\jdk12\jcg-zheng-interface-demo\target\surefire-reports ------------------------------------------------------- T E S T S ------------------------------------------------------- Running jcg.zheng.demo.api.impl.RuntimeTest Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.338 sec Results : Tests run: 2, Failures: 0, Errors: 0, Skipped: 0 [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 9.608 s [INFO] Finished at: 2019-06-25T21:42:03-05:00 [INFO] ------------------------------------------------------------------------
6.3 StaticMethodTest
In this step, I will create a StaticMethodTest class to test the interface’s static method.
StaticMethodTest.java
package jcg.zheng.demo.api.impl;
import org.junit.Test;
import jcg.zheng.demo.api.MusicalInstrument;
public class StaticMethodTest {
@Test
public void test_static_method() {
System.out.println(MusicalInstrument.repair());
}
}
Execute mvn test -Dtest=StaticMethodTest command and capture the output here.
Output
C:\MaryZheng\Workspaces\jdk12\jcg-zheng-interface-demo>mvn test -Dtest=StaticMethodTest [INFO] Scanning for projects... [INFO] [INFO] ---------< jcg-zheng-interface-demo:jcg-zheng-interface-demo >---------- [INFO] Building jcg-zheng-interface-demo 0.0.1-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ jcg-zheng-interface-demo --- [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory C:\MaryZheng\Workspaces\jdk12\jcg-zheng-interface-demo\src\main\resources [INFO] [INFO] --- maven-compiler-plugin:3.8.0:compile (default-compile) @ jcg-zheng-interface-demo --- [INFO] Changes detected - recompiling the module! [WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. build is platform dependent! [INFO] Compiling 17 source files to C:\MaryZheng\Workspaces\jdk12\jcg-zheng-interface-demo\target\classes [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ jcg-zheng-interface-demo --- [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory C:\MaryZheng\Workspaces\jdk12\jcg-zheng-interface-demo\src\test\resources [INFO] [INFO] --- maven-compiler-plugin:3.8.0:testCompile (default-testCompile) @ jcg-zheng-interface-demo --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ jcg-zheng-interface-demo --- [INFO] Surefire report directory: C:\MaryZheng\Workspaces\jdk12\jcg-zheng-interface-demo\target\surefire-reports ------------------------------------------------------- T E S T S ------------------------------------------------------- Running jcg.zheng.demo.api.impl.StaticMethodTest In good condition Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.123 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 9.069 s [INFO] Finished at: 2019-06-25T21:43:10-05:00 [INFO] ------------------------------------------------------------------------
7. Java Interface Example – Summary
In this example, I demonstrated how to define interfaces and create its implementation classes. Java interface provides the following benefits:
- Support polymorphism by sharing a standard set of methods in different ways.
- Support encapsulation by separating the method definition from the implementation.
- Supports multiple inheritances.
- Allow dependency injections during runtime
8. Download the Source Code
This example consists of a Maven project which defines five interfaces and nine implementation classes and three junit test classes to show the interface abstraction and runtime object injection.
You can download the full source code of this example here: Java Interface Example
Last updated on Feb. 12th, 2020

