| Home > Core Java FAQ
> Classes, Interfaces, & Packages FAQ |
| Classes,
Interfaces & Packages |
| Objects,
Classes, and Methods(19) * Sub
Class, Overload, and Overriding(11) * Interfaces
and Abstract Classes (11) * Packages
and Access Modifiers (09) |
| |
|
Q . What is an interface?
|
Ans :
In the Java
language, an interface is like a stripped-down class: it specifies
a set of methods that an instance must handle, but it omits
inheritance relations and method implementations.
Object-oriented
programming is sometimes modeled as communication between
objects—one object talks to, or sends a message to, another
object by invoking a method on it. In this view, an interface in
the Java language specifies the bare minimum one object needs to
know in order to talk to another object: a set of abstract methods
, that is, methods minus any implementation information. Put
another way, an interface specifies how you can talk to an object,
but says nothing about what kind of object will handle your
messages. It is the job of one or more class instances to provide
the substance behind an interface's promise.
Interfaces are a close cousin to
classes, and their declarations resemble class declarations. For
example, the Runnable interface in the java.lang
package (JDK 1.0.2 and 1.1) is declared as follows:
/* in Runnable.java (JDK 1.0.2 and 1.1): */
public interface Runnable {
public abstract void run();
}
An interface can
also contain static final variables, called class
constants; see The Java Language Specification, pp.
186-188, for details.
Interfaces provide the minimal level
of dependence between interacting objects. An interface focuses
purely on the role an object plays—what services it can
provide—without making any restrictions on the class of the
object.
|
|
Q .
How does a class implement an interface?
|
Ans
:
A class
implements an interface by declaring that it implements the
interface and by providing implementations for all methods
contained in the interface.
Despite
not having any implementation, an interface embodies both form and
intent. When you define an interface, you specify the set of
methods in the interface; you should also specify the intended
meaning of each method. Correspondingly, implementing an interface
requires that a class match the interface in both form and intent:
- the class
provides implementations for all the methods in the interface
- the class
declares explicitly that it implements the interface
Because both steps are
required, implementing an interface is guaranteed to be a
deliberate choice by the class's author. Simply having the same
methods as an interface is not sufficient.
For example, Applet
subclasses commonly implement the Runnable interface
in order to run themselves in a separate thread. The Runnable
interface in the java.lang package declares just a
single run method taking no parameters. A Runnable Applet subclass
must therefore declare that it implements the Runnable
interface and must define a run method:
public class MyApplet extends java.applet.Applet
implements Runnable
{
// ...
public void run() {
// ... code to run the applet in a separate thread
}
}
Note:
If a class implements an interface, all its subclasses
automatically implement the interface, too. Also, you can declare
that an abstract class implements an interface yet omit some
of the method declarations. This amounts to a promise (checked by
the compiler) that any concrete subclasses of that abstract class
will fully declare and implement the methods in the interface.
|
|
Q .
Can I instantiate an interface?
|
Ans
:
You can't;
you must instantiate a class that implements the interface.
Interfaces
specify a vocabulary of methods by which objects can communicate.
Instead of instantiating an interface, you instantiate a
class that implements the interface. You can then use that
object anywhere the interface type is required.
|
|
Q .
Why does a method in an interface appear to be public even though I didn't declare it to be public?
|
Ans
:
The Java
language defines all methods and variables in an interface to be
public, regardless of whether you use the public
keyword or not.
The
Java language requires that all methods and variables in an
interface be public. The compiler thus allows you to omit the public
keyword. Similarly, all methods in an interface are abstract, and
you do not need to include the abstract keyword in any interface
declarations.
The compiler will accept public and
abstract modifiers on interface methods for compatibility with
older code, but you are encouraged as a matter of style to omit
them (The Java Language Specification, p. 187).
|
|
Q .
How is an abstract class different from an interface?
|
Ans
:
Although
the Java language makes a clear distinction between abstract
classes and interfaces, in practice the difference is often a
matter of degree and intent.
Abstract
classes fill in the wide range between concrete classes and
interfaces. Table 1.5 lists several distinctions that are relevant
to typical uses.
Table
1.5: Concrete Class versus Abstract Class versus Interface
| Concrete
Class |
Abstract
Class |
Interface |
| specifies
the full set of methods for an object |
specifies
the full set of methods for an object |
specifies
a subset of methods for an object |
| implements
all of its methods |
implements
none, some, or all of its methods |
implements
none of its methods |
| can have
instances |
can't have
instances |
can't have
instances |
| can have
subclasses |
must have
subclasses; useless without them |
can't have
subclasses; must have classes that implement it; useless
without them |
If
the differences in Table 1.5 leave you uncertain about whether to
use an abstract class or an interface, one further factor may be
decisive. A class can have only one immediate superclass, but it
can implement any number of interfaces. An abstract class, even
one with all abstract methods, ties its subclasses to a particular
inheritance hierarchy. An interface, in contrast, leaves an object
free to implement other interfaces as needed by the object's
class.
Beyond the details, it is important
to understand how classes and interfaces differ in spirit. Classes
generally specify the full identity of an object: who/what it is
(its parentage), what roles it can perform (its vocabulary of
methods), and how it specifically performs those roles (its
implemented behavior). Interfaces specify neither parentage nor
behavior for an object—they focus exclusively on the role(s) an
object can play.
Consider, for example, the Observer
interface and Observable class in the java.util
package. An Observer object is one that
expects to be notified when an object it is watching (an Observable
object) changes state. An Observable object is one
that knows how to register, unregister, and notify a collection of
Observer objects.
The Observer interface
(JDK 1.0.2 and 1.1) defines a single method:
/* in Observer.java (JDK 1.0.2 and 1.1): */
public interface Observer {
void update(Observable o, Object arg);
}
Because Observer
is an interface, you can define whatever class you like to
implement the interface. For instance, you could define a Button
subclass to serve as an Observer:
public class ObserverButton extends Button
implements java.util.Observer {
public static void update(Observable o, Object arg) {
// ... respond to notification
}
}
This independence
of interfaces from any class hierarchy is a huge benefit.
In contrast, Observable is defined
as a class, which restricts all Observable objects to
belong to the Observable class or to a subclass of Observable.
Unlike ObserverButton above, you simply cannot define
an ObservableButton as a subclass of Button.
Java allows only single class inheritance, which forces you to
choose between one or the other inheritance hierarchy
|
|
Q .
Does the Java language allow multiple inheritance?
|
Ans :
Yes and no.
A
class in Java can implement any number of interfaces (multiple
interface inheritance) but can extend exactly one immediate
superclass, from which it inherits implementations (single class
inheritance).
Similarly, an interface can have any
number of superinterfaces, which are declared with the extends
keyword. For example:
// ... interfaces Readable, Writable declared elsewhere
public interface StreamInputOuput extends Readable, Writable {
// ... additional methods not in Readable or Writable
}
Finally,
does an interface have any superclasses? Yes, all interfaces are
treated as having one superclass: the Object class.
This amounts to a claim that whatever class implements the
interface will be a subclass of Object; the Java
language guarantees this to be true
|
|
Q . What is the instanceof keyword, and what does it do?
|
Ans
:
The instanceof
keyword is a two-argument operator that tests whether the run-time
type of its first argument is assignment compatible with its
second argument.
An
expression using instanceof, such as X
instanceof Y, tests whether the object referred to by X
could be assigned to a variable of type Y. If Y
is a class, this test checks whether X's object
belongs to class Y or to a subclass of Y.
If Y is an interface, the test checks if X's
object's class implements that interface.
The instanceof operator
performs tests at both compile time and run time. For example,
testing whether a String instance in a String
variable can be an instance of Integer fails at
compile time:
String aString = "abadcafe";
if (aString instanceof Integer) { /* ... */ }
The error message
from the JDK (1.0.2 and 1.1) compiler is unequivocal:
Impossible for java.lang.String to be instance of java.lang.Integer.
Failure at compile
time signals gross errors, such as checking two class types,
neither of which is a subclass of the other.
The primary use of instanceof,
however, is to check at run time the actual object type (run-time
type) of its left-hand argument, regardless of the static type of
the reference. For example, the AWT Component class
includes a getParent method that returns an object
reference of type Container. The actual (run-time)
type of the parent object, though, could be Panel, Applet,
Frame—any of a number of subclasses of Container.
You can then use the instanceof operator to test
which specific subclass you have:
/* code in your Component subclass: */
// ... myButton has been created and built into a user interface
Container cont = myButton.getParent();
if (cont instanceof Frame) { /* ... code to handle Frame ... */ }
|
|
Q .
Why do I get the error message Can't access protected method clone... when I try to clone an object?
|
Ans
:
The clone
method in class Object signals an
error if you invoke it on an object whose class does not
explicitly support cloning.
The
clone method in class Object creates a
new object that is essentially a bit-for-bit copy of the source
object. This is a simple but risky behavior for classes in
general, so classes are not allowed to inherit it by default.
(Remember that any nonprivate method in class Object
is potentially inherited by all other Java classes.) Object's clone
method thus has two built-in safety measures:
clone
is protected, which restricts access from outside
the java.lang package
clone
checks that the target object's class implements the cloneable
interface
The upshot of these
restrictions is that you can invoke clone on an
object only if that object's class has been designed explicitly to
allow cloning.
Cloning an object from a class set
up for cloning, however, is straightforward. You invoke clone
on an instance of that class, as in the following hypothetical
example:
DollarBill genuine = new DollarBill();
DollarBill counterfeit = (DollarBill) genuine.clone();
The clone
method returns an object reference of type Object,
which you must cast to the appropriate class.
|
|
Q .
How do I design a class so that it supports cloning?
|
Ans
:
Declare
that the class implements the cloneable
interface and override Object's clone
method with a version suited to your class.
Designing
a class that supports cloning involves two parts: a promise of
cloneability and a clone method to back it up. First,
you mark your class as fit for cloning by declaring that it
implements the cloneable interface. For example:
public class DollarBill implements cloneable { /* ... */ }
The cloneable
interface contains no methods; it is purely a flag.
Second, you define a clone
method that correctly copies the parts within each instance of
your class. Some parts of a class may require shallow copying;
others may require deep copying. Shallow copying merely
copies the value of a data element bit for bit—this is what the
default clone method in class Object does.
Shallow copying is appropriate when a data element directly
represents a value, such as an int, float, or boolean, rather than
a reference to a value. Shallow copying may occasionally be used
for reference values as well, the result being two references
sharing the same referred-to object. Deep copying is often
required for reference-type data elements. Deep copying creates
both a new reference and a new object for the reference to refer
to. The following code fragment sketches a DollarBill
class that performs both shallow and deep copying in its clone
method:
public class DollarBill implements cloneable {
int value = 1; // value of the bill (1, 5, 10, 20, ...)
String name; // personalized name given to individual bill
// ... constructors and various methods
/**
* clones a DollarBill by copying its value and making a deep
* copy of its String name.
*/
public Object clone() {
DollarBill copy = null;
try {
copy = (DollarBill) super.clone(); // shallow copy
copy.name = new String(this.name); // deep copying
} catch (cloneNotSupportedException e) {
e.printStackTrace();
}
return (Object) copy;
}
}
|
|
Q .
How do you do multiple inheritance?
|
Ans
:
Java does not support multiple inheritance. Instead declare interfaces for each additional class you want to inherit from, and implement those interfaces in your subclass.
|
|
Q .
What are the differences between an interface and an abstract class?
|
Ans
:
Some use a semantic distinction: an abstract superclass models the
"is" relationship, while an interface models the "has" relationship.The rule would be, if it's a subtype, inherit; otherwise, implement.
But, in the absence of real-world characteristics to distinguish the objects from their properties and parents, that becomes a circular
argument. In this case, you have to look at the practical differences
in Java (compared with C++).
Most differences between interfaces and abstract classes stem from three characteristics:
1. Both define method signatures that a derived class will have.
2. An abstract class can also define a partial implementation.
3. A class can implement many interfaces, but inherit from only one class.
|
|
|
|