Saturday 12 January 2013

Chapter 2: Object Orientation:Implementing an Interface

When you implement an interface, you're agreeing to adhere to the contract defined
in the interface. That means you're agreeing to provide legal implementations
for every method defined in the interface, and that anyone who knows what the
interface methods look like (not how they're implemented, but how they can be
called and what they return) can rest assured that they can invoke those methods on
an instance of your implementing class.

For example, if you create a class that implements the Runnable interface (so
that your code can be executed by a specific thread), you must provide the public
void run() method. Otherwise, the poor thread could be told to go execute your
Runnable object's code and—surprise surprise—the thread then discovers the object
has no run() method! (At which point, the thread would blow up and the JVM
would crash in a spectacular yet horrible explosion.) Thankfully, Java prevents this
meltdown from occurring by running a compiler check on any class that claims
to implement an interface. If the class says it's implementing an interface, it darn
well better have an implementation for each method in the interface (with a few
exceptions we'll look at in a moment).

Assuming an interface, Bounceable, with two methods: bounce(), and
setBounceFactor(), the following class will compile:

public class Ball implements Bounceable
{ // Keyword
   // 'implements'
    public void bounce()
    {
    }

    public void setBounceFactor(int bf)
    {
    }
}


OK, we know what you're thinking: "This has got to be the worst implementation
class in the history of implementation classes." It compiles, though. And runs. The
interface contract guarantees that a class will have the method (in other words,
others can call the method subject to access control), but it never guaranteed a
good implementation—or even any actual implementation code in the body of the
method. The compiler will never say to you, "Um, excuse me, but did you reallymean to put nothing between those curly braces? HELLO. This is a method after all,
so shouldn't it do something?"
Implementation classes must adhere to the same rules for method implementation
as a class extending an abstract class. In order to be a legal implementation class, a
nonabstract implementation class must do the following:

-Provide concrete (nonabstract) implementations for all methods from the
declared interface.
- Follow all the rules for legal overrides.
- Declare no checked exceptions on implementation methods other than
those declared by the interface method, or subclasses of those declared by
the interface method.
- Maintain the signature of the interface method, and maintain the same
return type (or a subtype). (But it does not have to declare the exceptions
declared in the interface method declaration.)

But wait, there's more! An implementation class can itself be abstract! For
example, the following is legal for a class Ball implementing Bounceable:

abstract class Ball implements Bounceable { }

class BeachBall extends Ball
{
    // Even though we don't say it in the class declaration above,
    // BeachBall implements Bounceable, since BeachBall's abstract
    // superclass (Ball) implements Bounceable
    public void bounce()
    {
        // interesting BeachBall-specific bounce code
    }

    public void setBounceFactor(int bf)
    {
        // clever BeachBall-specific code for setting
        // a bounce factor
    }
    // if class Ball defined any abstract methods,
    // they'll have to be
    // implemented here as well.
}

Look for classes that claim to implement an interface but don't provide the
correct method implementations. Unless the implementing class is abstract, the
implementing class must provide implementations for all methods defined in the
interface.
Two more rules you need to know and then we can put this topic to sleep (or put
you to sleep; we always get those two confused):
1. A class can implement more than one interface. It's perfectly legal to say, for
example, the following:

public class Ball implements Bounceable, Serializable, Runnable
{ ... }

You can extend only one class, but implement many interfaces. But remember
that subclassing defines who and what you are,whereas implementing defines a role
you can play
or a hat you can wear, despite how different you might be from some
other class implementing the same interface(but from a different inheritance tree).
For example, a Person extends HumanBeing (although for some, that's debatable).
But a Person may also implement Programmer, Snowboarder, Employee, Parent, or
PersonCrazyEnoughToTakeThisExam.

2. An interface can itself extend another interface, but never implement
anything. The following code is perfectly legal:

public interface Bounceable extends Moveable { } // ok!

Hold on though, because here's where it gets strange. An interface can extend
more than one interface! Think about that for a moment. You know that when we're
talking about classes, the following is illegal:

public class Programmer extends Employee, Geek { } // Illegal!

As we mentioned earlier, a class is not allowed to extend multiple classes in Java.
An interface, however, is free to extend multiple interfaces.

interface Bounceable extends Moveable, Spherical
{ // ok!
    void bounce();

    void setBounceFactor(int bf);
}

interface Moveable
{
    void moveIt();
}

interface Spherical
{
    void doSphericalThing();
}

In the next example, Ball is required to implement Bounceable, plus all methods
from the interfaces that Bounceable extends (including any interfaces those
interfaces extend, and so on until you reach the top of the stack—or is it the bottom
of the stack?). So Ball would need to look like the following:

class Ball implements Bounceable
{
    public void bounce()
    {
    } // Implement Bounceable's methods

    public void setBounceFactor(int bf)
    {
    }

    public void moveIt()
    {
    } // Implement Moveable's method

    public void doSphericalThing()
    {
    } // Implement Spherical
}

If class Ball fails to implement any of the methods from Bounceable, Moveable, or
Spherical, the compiler will jump up and down wildly, red in the face, until it does.
Unless, that is, class Ball is marked abstract. In that case, Ball could choose to
implement any, all, or none of the methods from any of the interfaces, thus leaving
the rest of the implementations to a concrete subclass of Ball, as follows:

abstract class Ball implements Bounceable
{
    public void bounce() { ... } // Define bounce behavior

    public void setBounceFactor(int bf) { ... }
    // Don't implement the rest; leave it for a subclass
}

class SoccerBall extends Ball
{ // class SoccerBall must
// implement the interface methods that Ball didn't
    public void moveIt() { ... }

    public void doSphericalThing() { ... }

    // SoccerBall can choose to override the Bounceable methods
    // implemented by Ball
    public void bounce() { ... }
}

Comparing Concrete and Abstract Examples of Extends and Implements





class Foo { } // OK
class Bar implements Foo { } // No! Can't implement a class
interface Baz { } // OK
interface Fi { } // OK
interface Fee implements Baz { } // No! Interface can't
// implement an interface
interface Zee implements Foo { } // No! Interface can't
// implement a class
interface Zoo extends Foo { } // No! Interface can't
// extend a class
interface Boo extends Fi { } // OK. Interface can extend
// an interface
class Toon extends Foo, Button { } // No! Class can't extend
// multiple classes
class Zoom implements Fi, Fee { } // OK. class can implement
// multiple interfaces
interface Vroom extends Fi, Fee { } // OK. interface can extend
// multiple interfaces
class Yow extends Foo implements Fi { } // OK. Class can do both
// (extends must be 1st)



Burn these in, and watch for abuses in the questions you get on the
exam. Regardless of what the question appears to be testing, the real problem might be
the class or interface declaration. Before you get caught up in, say, tracing a complex
threading flow, check to see if the code will even compile. (Just that tip alone may
be worth your putting us in your will!) (You’ll be impressed by the effort the exam
developers put into distracting you from the real problem.) (How did people manage to
write anything before parentheses were invented?)

No comments:

Post a Comment