Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
9 views

Java Mod 3 Interfaces

The document provides a comprehensive overview of interfaces in Java, detailing how they allow for abstraction by defining method signatures without implementations. It explains the concept of default methods introduced in JDK 8, which enable interfaces to provide default implementations, thus allowing for backward compatibility when evolving interfaces. Additionally, the document covers nested interfaces, multiple inheritance issues, and the introduction of static methods in interfaces, emphasizing the flexibility and structure they bring to Java programming.

Uploaded by

keerthana L.M
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views

Java Mod 3 Interfaces

The document provides a comprehensive overview of interfaces in Java, detailing how they allow for abstraction by defining method signatures without implementations. It explains the concept of default methods introduced in JDK 8, which enable interfaces to provide default implementations, thus allowing for backward compatibility when evolving interfaces. Additionally, the document covers nested interfaces, multiple inheritance issues, and the introduction of static methods in interfaces, emphasizing the flexibility and structure they bring to Java programming.

Uploaded by

keerthana L.M
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 40

INTERFAC

ES
INTERFACES
• Using the keyword interface, you can fully abstract a class’ interface from its
implementation.
• That is, using interface, you can specify what a class must do, but not how it does it.
• Interfaces are syntactically similar to classes, but they lack instance variables, and
their methods are declared without any body.
• In practice, this means that you can define interfaces which don’t make assumptions
about how they are implemented.
• Once it is defined, any number of classes can implement an interface.
• Also, one class can implement any number of interfaces.
• To implement an interface, a class must create the complete set of methods defined by
the interface.
• However, each class is free to determine the details of its own implementation.
• By providing the interface keyword, Java allows you to fully utilize the “one interface,
multiple methods” aspect of polymorphism.
Defining an Interface
• General form of an interface: • Notice that the methods which are declared have
no bodies. They end with a semicolon after the
parameter list.
• They are, essentially, abstract methods; there can
be no default implementation of any method
specified within an interface.
• Each class that includes an interface must
implement all of the methods.
• Variables can be declared inside of interface
declarations. They are implicitly final and static,
meaning they cannot be changed by the
implementing class.
• They must also be initialized with a constant
value.
• Here, access is either public or • All methods and variables are implicitly public if
not used. the interface, itself, is declared as public.
interface Callback {
• name is the name of the interface,
void callback(int param);
and can be any valid identifier.
}
Implementing Interfaces
• Once an interface has been
defined, one or more classes can
implement that interface.
• To implement an interface,
include the implements clause in
a class definition, and then create
the methods defined by the
interface.
• General form of a class that
includes the implements clause
looks like this:
Accessing Implementations Through Interface
References

• The following example calls the callback( ) method via an


interface reference variable:
Partial Implementations
• If a class includes an interface but does not fully implement the
methods defined by that interface, then that class must be
declared as abstract.
• For example:

• Here, the class Incomplete does not implement callback( ) and


must be declared as abstract. Any class that inherits Incomplete
must implement callback( ) or be declared abstract itself.
Nested Interfaces
• An interface can be declared a member of a class or another interface.
• Such an interface is called a member interface or a nested interface.
• A nested interface can be declared as public, private, or protected.
• This differs from a top-level interface, which must either be declared as public or use the default
access level, as previously described.
• When a nested interface is used outside of its enclosing scope, it must be qualified by the name of the
class or interface of which it is a member.
• Thus, outside of the class or interface in which a nested interface is declared, its name must be fully
qualified.
Here is an example that demonstrates a nested
class NestedIFDemo {
interface:
public static void main(String[]
// A nested interface example.
args) {
// This class contains a member interface.
// use a nested interface reference
class A {
A.NestedIF nif = new B();
// this is a nested interface
if(nif.isNotNegative(10))
public interface NestedIF {
System.out.println("10 is not
boolean isNotNegative(int x);
negative");
}
if(nif.isNotNegative(-12))
}
System.out.println("this won't be
// B implements the nested interface.
displayed");
class B implements A.NestedIF {
}
public boolean isNotNegative(int x) {
}
return x < 0 ? false: true;
}
}
• Notice that A defines a member interface called NestedIF and that it is declared public.
• Next, B implements the nested interface by specifying implements A.NestedIF Notice that the name
is fully qualified by the enclosing class’ name. Inside the main( ) method, an A.
• NestedIF reference called nif is created, and it is assigned a reference to a B object. Because B
implements A.NestedIF, this is legal.
Applying
Interfaces
• Dynamic stack
Variables in Interfaces
Interfaces Can Be
Extended
Default Interface Methods:
• Prior to JDK 8, an interface could not define any implementation whatsoever.
• This meant that for all previous versions of Java, the methods specified by an interface were abstract,
containing no body.
• This is the traditional form of an interface and is the type of interface that the preceding discussions have used.
The release of JDK 8 changed this by adding a new capability to interface called the default method.
• A default method lets you define a default implementation for an interface method.
• In other words, by use of a default method, it is possible for an interface method to provide a body, rather than
being abstract.
• During its development, the default method was also referred to as an extension method, and you will likely
see both terms used.
• A primary motivation for the default method was to provide a means by which interfaces could be
expanded without breaking existing code.
• Recall that there must be implementations for all methods defined by an interface.
• In the past, if a new method were added to a popular, widely used interface, then the addition of
that method would break existing code because no implementation would be found for that new
method.
• The default method solves this problem by supplying an implementation that will be used if no
other implementation is explicitly provided.
• Thus, the addition of a default method will not cause preexisting code to break.
• Another motivation for the default method was the desire to specify methods in an interface that are, essentially,
optional, depending on how the interface is used.
• For example, an interface might define a group of methods that act on a sequence of elements.
• One of these methods might be called remove( ), and its purpose is to remove an element from the sequence.
However, if the interface is intended to support both modifiable and nonmodifiable sequences, then remove( ) is
essentially optional because it won’t be used by nonmodifiable sequences.
• In the past, a class that implemented a nonmodifiable sequence would have had to define an empty
implementation of remove( ), even though it was not needed.
• Today, a default implementation for remove( ) can be specified in the interface that does nothing (or throws an
exception). Providing this default prevents a class used for nonmodifiable sequences from having to define its
own, placeholder version of remove( ).
• Thus, by providing a default, the interface makes the implementation of remove( ) by a class optional.
• It is important to point out that the addition of default methods does not change a key aspect of
interface: its inability to maintain state information.
• An interface still cannot have instance variables, for example. Thus, the defining difference
between an interface and a class is that a class can maintain state information, but an interface
cannot.
• Furthermore, it is still not possible to create an instance of an interface by itself. It must be
implemented by a class.
• Therefore, even though, beginning with JDK 8, an interface can define default methods, the
interface must still be implemented by a class if an instance is to be created.
• One last point: As a general rule, default methods constitute a special-purpose feature. Interfaces
that you create will still be used primarily to specify what and not how.
• However, the inclusion of the default method gives you added flexibility.
Default Method Fundamentals
An interface default method is defined similar to the way a method is defined by a class. The primary
difference is that the declaration is preceded by the keyword default. For example, consider this simple
interface:
public interface MyIF {
// This is a "normal" interface method declaration.
// It does NOT define a default implementation.
int getNumber();
// This is a default method. Notice that it provides
// a default implementation.
default String getString() {
return "Default String";
}
}
• MyIF declares two methods.
• The first, getNumber( ), is a standard interface method declaration.
• It defines no implementation whatsoever.
• The second method is getString( ), and it does include a default implementation. In this case, it simply returns
the string "Default String".
• Pay special attention to the way getString( ) is declared. Its declaration is preceded by the default modifier.
• This syntax can be generalized. To define a default method, precede its declaration with default.
• Because getString( ) includes a default implementation, it is not necessary for an implementing class
to override it.
• In other words, if an implementing class does not provide its own implementation, the default is
used. For example, the MyIFImp class shown next is perfectly valid:

// Implement MyIF.
class MyIFImp implements MyIF {
// Only getNumber() defined by MyIF needs to be
implemented.
// getString() can be allowed to default.
public int getNumber() {
return 100;
}
}
The following code creates an instance of MyIFImp and uses it to call both getNumber( ) and
getString( ).
// Use the default method.
class DefaultMethodDemo {
public static void main(String[] args) {
MyIFImp obj = new MyIFImp();
// Can call getNumber(), because it is explicitly
// implemented by MyIFImp:
System.out.println(obj.getNumber());
// Can also call getString(), because of default
// implementation:
System.out.println(obj.getString());
}
}

The output is shown here:


100
Default String
• As you can see, the default implementation of getString( ) was automatically used.
• It was not necessary for MyIFImp to define it.
• Thus, for getString( ), implementation by a class is optional. (Of course, its implementation by a
class will be required if the class uses getString( ) for some purpose beyond that supported by its
default.)
• It is both possible and common for an implementing class to define its own implementation of a
default method.
• For example, MyIFImp2 overrides getString( ):
class MyIFImp2 implements MyIF {
// Here, implementations for both getNumber( ) and getString( ) are provided.
public int getNumber() {
return 100;
}
public String getString() {
return "This is a different string.";
}
}
Now, when getString( ) is called, a different string is returned.
A More Practical Example
• Although the preceding shows the mechanics of using default methods, it doesn’t illustrate their
usefulness in a more practical setting.
• To do this, let’s once again return to the IntStack interface shown earlier in this chapter. For the sake
of discussion, assume that IntStack is widely used and many programs rely on it.
• Further assume that we now want to add a method to IntStack that clears the stack, enabling the
stack to be re-used.
• Thus, we want to evolve the IntStack interface so that it defines new functionality, but we don’t
want to break any preexisting code.
• In the past, this would be impossible, but with the inclusion of default methods, it is now easy to do.
For example, the IntStack interface can be enhanced like this:
interface IntStack {
void push(int item); // store an item
int pop(); // retrieve an item
// Because clear( ) has a default, it need not be
// implemented by a preexisting class that uses IntStack.
default void clear() {
System.out.println("clear() not implemented.");
}
}
• Here, the default behavior of clear( ) simply displays a message indicating that it is not
implemented.
• This is acceptable because no preexisting class that implements IntStack would ever call clear( )
because it was not defined by the earlier version of IntStack.
• However, clear( ) can be implemented by a new class that implements IntStack.
• Furthermore, clear( ) needs to be defined by a new implementation only if it is used.
• Thus, the default method gives you a way to gracefully evolve interfaces over time, and a way to
provide optional functionality without requiring that a class provide aplaceholder implementation
when that functionality is not needed.
• One other point: In real-world code, clear( ) would have thrown an exception, rather than displaying
an error message.
• Exceptions are described in the next chapter. After working through that material, you might want to
try modifying clear( ) so that its default implementation throws
anUnsupportedOperationException.
Multiple Inheritance Issues
• As explained earlier in this book, Java does not support the multiple inheritance of classes. Now that
an interface can include default methods, you might be wondering if an interface can provide a way
around this restriction.
• The answer is, essentially, no. Recall that there is still a key difference between a class and an
interface: a class can maintain state information (especially through the use of instance variables),
but an interface cannot.
• The preceding notwithstanding, default methods do offer a bit of what one would normally associate
with the concept of multiple inheritance.
• For example, you might have a class that implements two interfaces. If each of these interfaces provides
default methods, then some behavior is inherited from both.
• Thus, to a limited extent, default methods do support multiple inheritance of behavior. As you might guess, in
such a situation, it is possible that a name conflict will occur.
• For example, assume that two interfaces called Alpha and Beta are implemented by a class called MyClass.
What happens if both Alpha and Beta provide a method called reset( ) for which both declare a default
implementation? Is the version by Alpha or the version by Beta used by MyClass? Or, consider a situation in
which Beta extends Alpha.
• Which version of the default method is used? Or, what if MyClass provides its own implementation of the
method? To handle these and other similar types of situations, Java defines a set of rules that resolves such
conflicts.
• First, in all cases, a class implementation takes priority over an interface default implementation.
• Thus, if MyClass provides an override of the reset( ) default method, MyClass’ version is used.
• This is the case even if MyClass implements both Alpha and Beta.
• In this case, both defaults are overridden by MyClass’ implementation.
• Second, in cases in which a class implements two interfaces that both have the same default method, but the
class does not override that method, then an error will result.
• Continuing with the example, if MyClass implements both Alpha and Beta, but does not override reset( ),
then an error will occur.
• In cases in which one interface inherits another, with both defining a common default method, the inheriting
interface’s version of the method takes precedence. Therefore, continuing the example, if Beta extends Alpha,
then Beta’s version of reset( ) will be used. It is possible to explicitly refer to a default implementation in an
inherited interface by using this form of super. Its general form is shown here:
InterfaceName.super.methodName( )
• For example, if Beta wants to refer to Alpha’s default for reset( ), it can use this statement:
Alpha.super.reset();
se static Methods in an Interface
• Another capability added to interface by JDK 8 is the ability to define one or more
static methods.
• Like static methods in a class, a static method defined by an interface can be called
independently of any object.
• Thus, no implementation of the interface is necessary, and no instance of the
interface is required, in order to call a static method.
• Instead, a static method is called by specifying the interface name, followed by a
period, followed by the method name.
• Here is the general form:
InterfaceName.staticMethodName
• Notice that this is similar to the way that a static method in a class is called.

• The following shows an example of a static method in an interface by adding one to


MyIF, shown in the previous section.
• The static method is getDefaultNumber( ).
• It returns zero.
public interface MyIF {
// This is a "normal" interface method declaration.
// It does NOT define a default implementation.
int getNumber();
// This is a default method. Notice that it provides
// a default implementation.
• The getDefaultNumber( ) method can be called, as
default String getString() { shown here:
return "Default String"; int defNum = MyIF.getDefaultNumber();
} • As mentioned, no implementation or instance of
// This is a static interface method. MyIF is required to call getDefaultNumber( )
because it is static.
static int getDefaultNumber() {
• One last point: static interface methods are not
return 0; inherited by either an implementing class or a
} subinterface.
}
Private Interface Methods
• Beginning with JDK 9, an interface can include a private method.
• A private interface method can be called only by a default method or another
private method defined by the same interface.
• Because a private interface method is specified private, it cannot be used by code
outside the interface in which it is defined.
• This restriction includes subinterfaces because a private interface method is not
inherited by a subinterface.
• The key benefit of a private interface method is that it lets two or more default
methods use a common piece of code, thus avoiding code duplication.
• For example, here is another version of the IntStack interface that has two default
methods called popNElements( ) and skipAndPopNElements( ).
• The first returns an array that contains the top N elements on the stack.
• The second skips a specified number of elements and then returns an array that
contains the next N elements.
• Both use a private method called getElements( ) to obtain an array of the
specified number of elements from the stack.
// Another version of IntStack that has a // A private method that returns an
private interface array containing
// method that is used by two default // the top n elements on the stack
methods. private int[] getElements(int n) {
interface IntStack { int[] elements = new int[n];
void push(int item); // store an item for(int i=0; i < n; i++) elements[i] =
int pop(); // retrieve an item pop();
// A default method that returns an array that return elements;
contains }
// the top n elements on the stack. }
default int[] popNElements(int n) {
// Return the requested elements.
return getElements(n);
}
// A default method that returns an array that
contains
// the next n elements on the stack after
skipping elements.
default int[] skipAndPopNElements(int skip,
int n) {
• Notice that both popNElements( ) and skipAndPopNElements( ) use the private
getElements( ) method to obtain the array to return.
• This prevents both methods from having to duplicate the same code sequence. Keep
in mind that because getElements( ) is private, it cannot be called by code outside
IntStack.
• Thus, its use is limited to the default methods inside IntStack.
• Also, because getElements( ) uses the pop( ) method to obtain stack elements, it
will automatically call the implementation of pop( ) provided by the IntStack
implementation.
• Thus, getElements( ) will work for any stack class that implements IntStack.
Although the private interface method is a feature that you will seldom need, in
those cases in which you do need it, you will find it quite useful.
nal Thoughts on Packages and Interfaces
• Although the examples we’ve included in this book do not make frequent use of
packages or interfaces, both of these tools are an important part of the Java
programming environment.
• Virtually all real programs that you write in Java will be contained within
packages.
• A number will probably implement interfaces as well.
• It is important, therefore, that you be comfortable with their usage.

You might also like