Declaring an Interface

0

In my last article, I showed you examples of abstract classes. In this article, I will show how to declare an interface.

Interface defines what a class can do and leaves the ‘how’ part to the class. It contains only the abstract methods without any implementation. If a class implements the interface it has to either implement all the methods or declare itself as abstract.

package javarticles.interfaceexamples;

public interface Playable {
    void play();
}

VideoPlayer implements Playable.

package javarticles.interfaceexamples;

public class VideoPlayer implements Playable {

}

If it doesn’t implement the play(), compiler will issue error: The type VideoPlayer must implement the inherited abstract method Playable.play()

Any class type that implements playable must know how to play().
You can have more implementations of Playable like VideoPlayer, AudioPlayer

package javarticles.interfaceexamples;

public class VideoPlayer implements Playable {
    @Override
    public void play() {
        System.out.println("Play video");        
    }

}

AudioPlayer

package javarticles.interfaceexamples;

public class AudioPlayer implements Playable {
    @Override
    public void play() {
         System.out.println("Playing audio...");
    }
}

A class can implement multiple interfaces where each interface defines a specific character. For example, I can have an interface called Media which returns me the type of media and make the AudioPlayer implement both Playable and Media interfaces.

package javarticles.interfaceexamples;

public interface Media {
    MediaType getMediaType();
    public enum MediaType {
        AUDIO,
        VIDEO,
        IMAGES
    }
}
package javarticles.interfaceexamples.media;

import javarticles.interfaceexamples.Playable;

public class AudioPlayer implements Playable, Media {
    @Override
    public void play() {
         System.out.println("Playing audio...");
    }

    @Override
    public MediaType getMediaType() {
        return MediaType.AUDIO;
    }
}

Interface can be implemented by classes belonging to different hierarchies. For example, Playable can be implemented by media types like audio and video, as well as musical instruments like Piano and Violin.

Suppose I have a set of musical tones where each tone represents an instrument. I will make each musical tone implement Instrumental so that I know the type of the instrument the tone represents.

package javarticles.interfaceexamples.music;

public interface Instrumental {
    String getInstrumentType();
}

If it is an instrument, we should also be able to play its tone. So class PianoTone may implement Instrumental as well as Playable

package javarticles.interfaceexamples.music;

import javarticles.interfaceexamples.Playable;

public class PianoTone implements Instrumental, Playable{

    @Override
    public void play() { 
        System.out.println("Play " + getInstrumentType());
    }

    @Override
    public String getInstrumentType() {
        return "Piano";
    }

}

ViolinTone:

package javarticles.interfaceexamples.music;

import javarticles.interfaceexamples.Playable;

public class ViolinTone implements Instrumental, Playable {

    @Override
    public void play() {
        System.out.println("Play " + getInstrumentType());
    }

    @Override
    public String getInstrumentType() {
        return "Violin";
    }

}

Thus both media type and instruments share Playable interface even though they are not in the same hierarchy.

Access control of Interface

Interface defines the contract, it can be declared as public or default. If default, classes from other packages won’t be able to implement it.

Example of an interface with default access:

package javarticles.interfaceexamples.music;

interface Instrumental {
    String getInstrumentType();
}

Suppose ViolinAudioPiece from some other package tries to implement Instrumental, compiler will throw error:

package javarticles.interfaceexamples.media;

import java.lang.instrument.Instrumentation;

public class ViolinAudioPiece implements Instrumental {
}

Instrumental cannot be resolved to a type

Interface and Abstract class

Interface is purely abstract. Interface itself can be either default or public but the methods it contain are always abstract and public.

Which means

interface Instrumental {
    String getInstrumentType();
}
interface Instrumental {
    abstract String getInstrumentType();
}
interface Instrumental {
    public abstract String getInstrumentType();
}

all are same.

An abstract class can define both abstract and non-abstract methods but methods in interface are always abstract. You do not need to explicitly declare it as abstract and public, the methods are always public and abstract.

Illegal method declarations in an interface

final void play()
An interface method can never be final else the class implementing the interface will never be able to implement it. Also, remember abstract and final can never go together.

static void play()
We can never have static methods in interface. The methods are always instance methods which is why different classes can implement an interface and provide there own implementation.

private void play()
Interface methods can never be private. Remember interface is just a contract which depends on some class to implement the behavior. If a method is private, class implementing the interface won’t be able to implement it.

protected void play()
Interface methods will always be public. You can use the default access modifier at interface level to control its visibility. Even though the methods can’t be protected, they can still be overridden by the sub-classes implementing the interface.

Fields in interface

Interface can declare only constants and not instance variables which means they are implicitly always public, static and final whether you declare it explicitly or not.

For example, suppose I have two constants in Media interface.

package javarticles.interfaceexamples.media;

public interface Media {
    int AUDIO_TYPE = 0;
    int VIDEO_TYPE = 1;
}

I shouldn’t be able to change the constant value.

    public void testInterfaceConstants() {
        Media.AUDIO_TYPE = 2;
    }

Compiler throws error:
The final field Media.AUDIO_TYPE cannot be assigned

About Author

Ram’s expertise lies in test driven development and re-factoring. He is passionate about open source technologies and loves blogging on various java and open-source technologies like spring.
You can reach him at [email protected]

Leave A Reply