| 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 object?
|
Ans :
An object
is a software unit that combines a structured set of data with a
set of operations for inspecting and manipulating that data.
Object-oriented
programming reverses the function-data relationship familiar from
non-object-oriented languages, such as C. Programs in C (similarly
Pascal, or Basic) are often based on direct data manipulation:
they define data structures and provide functions that inspect or
change that data from anywhere else in the program. Intimate
knowledge of data structures can be spread throughout the program,
and changing a structure in one part can have drastic consequences
for many other parts of the program.
Object-oriented programming provides
standard tools and techniques for reducing dependencies between
different parts of a program. An object starts with a structured
set of data, but also includes a set of operations for inspecting
and manipulating that data. In an object, all operations that
require intimate knowledge of the data structure are directly
associated with the structure, rather than being spread throughout
the program.
A class defines a
type of object. It defines the data an object can hold and the methods
for operating on that data. Each object belongs to some class and
is called an instance of that class.
Grouping operations together with
their data permits you to request operations from the object
rather than directly manipulating the object's data. This
seemingly small step has the great benefit of decoupling the
requester of an operation from the performer. The requester (some
part of the program) need know only what actions to request; the
performer (the object) is responsible for the detailed knowledge
of how to fulfill the requests. Parts of a program now depend on
each other, not through data structures, but through functionality
they promise to provide (sometimes called the "contract"
of each participating class).
The Java™ programming language is
object-oriented, which means that classes, instances, and methods
constitute the core of your program's design.
|
|
Q .
What is a class?
|
Ans
:
A class is
a blueprint for objects: it defines a type of object according to
the data the object can hold and the operations the object can
perform.
Classes
are the fundamental units of design in object-oriented
programming. A class is a pattern that defines a kind of object.
It specifies a data structure for the object together with a set
of operations for acting on the object's data. A class is usually
also a factory that creates objects. You can use a class to create
one or more objects (instances of the class) when the program is
run. Each instance carries its own data, such that you can change
one instance and leave others unaffected. Classes specify
capabilities for objects, and objects do the actual work.
The Java String class,
for example, defines an object type for character strings. A String
instance holds a sequence of Unicode characters and provides a
large number of methods for getting information about that string.
Although there is just one String class, there can be
any number of String instances (objects) in a Java
program.
A class declaration in Java looks
much like a struct declaration in C. It contains at
the very least the class keyword, the class's name,
an opening brace, and a closing brace. Class declarations also
have many optional parts, such as access modifiers, a superclass
specification, interface specifications , and various parts in the
body of the class. The following simple example defines a class
with one piece of data (called a field) and one method
for acting on that data:
class SimpleClass {
int count; // field
void incrementCount() {
++count;
}
}
Understanding
the difference between a class and an instance is one of the
fundamental steps in learning object-oriented programming. Table
1.1 shows a few analogies for this difference:
Table 1.1:
Class versus Instance
| Class |
Instance |
| cookie recipe
and cutter |
cookie |
| housing tract
blueprint |
specific house |
| rubber stamp |
stamped image |
| photographic
negative |
printed
picture |
Note:
From here on, this book follows The Java Language
Specification (JLS; p. 38) in using the term object
to refer to class instances and arrays. This broader use
of the term takes a little getting used to but is clear and
consistent. Where only class instances are under discussion, they
will be referred to as class instances or simply instances.
|
|
Q .
How do I version a class?
|
Ans
: There is no support for versioning classes in Java 1.0. However in Java 1.1 the serialver tool provides a serialVersionUID for one or more classes you can add to your class as a field. This is used in object serialization.
|
|
Q .
What is a method?
|
Ans
:
A method is
the basic unit of functionality in an object-oriented language—a
body of executable code that belongs to a class and that can be
applied to (invoked on) a specific object or the class
itself.
Methods
are the object-oriented counterpart to functions or subroutines.
Like a function, a method consists of:
- a name
- a (possibly
empty) list of input names, called parameters, and their types
- an (optional)
output type, called the return type (the
void
keyword declares that a method has no return type)
- a body of
executable code
The following code
fragment declares a method whose output (of type double)
is the average of its two input values (also of type double):
double average(double a, double b) {
return (a + b) / 2.0;
}
Because methods
belong to classes, you can define a method only in the body of a
class definition. Note that the code fragment, however, follows
the convention of this book in not showing the enclosing class
definition unless relevant.
You usually use a method to inspect
or manipulate the data stored in an object. For example, the Java
String class provides a length method for
determining the length of a String instance. The length
method has no parameters and its return value is an int
indicating the length of the String instance you
invoke it on; for instance:
String aString = "Bicycle Shop Quarterly News" ;
int howLong = aString.length();
Methods
are not simply activated—they are invoked on a specific
object (or on a class). Consider the following code, which creates
two Abstract Window Toolkit (AWT) Button instances
and then sets the label for each one:
/* in Java: */
Button button1 = new Button();
Button button2 = new Button();
button1.setText("Push Me First");
button2.setText("Push Me Second");
Invoking setText
on button1 amounts to asking the Button class to look
up its definition for setText and then execute that
code with respect to the data in button1. Invoking setText
on button2 results in the same method lookup, but the
resulting code is applied to button2 rather than button1.
In a non-object-oriented language, such as C, you might use an
equivalent setButtonText function that includes the
button explicitly as an argument:
/* in C: */
struct Button *button1 = makeButton();
struct Button *button2 = makeButton();
setButtonText(button1, "Push Me First");
setButtonText(button2, "Push Me Second")
(For further
discussion of the relationship between a struct in C
and an object in Java)
Because each class is responsible
for its own methods, different classes can use the same name,
parameters, and return type, yet still define different methods.
For example, the AWT Label class also defines a setText
method that takes a String parameter:
/* using Label's setText method rather than Button's: */
Label aLabel = new Label();
aLabel.setText("Read me — I'm a label.");
In this example,
the Label class provides its own definition for setText,
and this definition could be entirely different from what the Button
class provides.
The ability of different methods to
look alike from the caller's perspective is a crucial part of
object-oriented programming: it separates the request for action
from the details of how that request is fulfilled. Your code can
invoke a method on an object without having to know the exact
class of the object—only that it has a method with the same
name, parameter list, and return type (Q1.14).
What actual code gets executed is selected by the class of the
target object, not by the invoker.
|
|
Q .
What is the signature of a method?
|
Ans
:
The
signature of a method is the combination of the method's name and
the method's input types (that is, number of parameters and their
types).
The
signature of a method provides precisely enough information to
identify a method uniquely within a given class. Put another way,
each method signature functions as a distinct lookup key when the
class maps from method invocations to executable method bodies.
For example, the following are
signatures for several methods in the Java AWT Rectangle
class (in the JDK 1.1):
isEmpty()
intersection(Rectangle)
setLocation(int,
int)
contains(int,
int)
contains(Point)
(Note that method
signatures as represented here are not valid Java code; they
represent only the information in the signature itself.) The
method signatures in a, b, and c differ from each other in every
way—name, number of parameters, and types of parameters; items c
and d differ only in name; and items d and e match in name but
differ in number and types of parameters.
It is important to remember that a
method's output information—its return value or declared
exceptions—does not contribute to the method's signature. The
compiler uses this information, though, to check the validity of
method overriding
|
|
Q . What is the difference between an instance variable and a class variable?
|
Ans :
An instance
variable represents a separate data item for each instance of a
class, whereas a class variable represents a single data item
shared by the class and all its instances.
An
instance variable represents data for which each instance has its
own copy. An instance variable corresponds roughly to a field of a
structure (struct) in C or C++. If your program
contains twenty Button instances, for example, each
instance has its own label instance variable holding
the label string for that button.
A class variable, in contrast,
belongs to the class as a whole. All instances of the class have
access to the same single copy. A class variable can therefore
function as a shared resource and an indirect means of
communication among the instances of the class. Class variables
are declared with the static keyword.
The following code fragment declares
a class with two instance variables and one class variable:
class Example {
int i1; // no static keyword, therefore instance variable
String s;
static int i2; // static keyword, therefore class variable
}
|
|
Q . What is the difference between an instance method and a class method?
|
Ans
:
An instance
method has a this instance reference, whereas a class
method does not.
An
instance method always works hand in hand with a class instance.
An instance method must be invoked on a specific class instance,
and it has special access to the data in that instance. For
example:
String s1 = "abcde"; // one String instance
String s2 = "fgh"; // another String instance
int i1 = s1.length(); // i1 = 5
int i2 = s2.length(); // i2 = 3
The length
method returns the number of characters in its target object (s1
or s2 in this example), just as if that target were
an argument to a length function (cf. strlen(aString)
in C). When defining an instance method, you can use the this
keyword to refer to the target instance.
Class methods have no target
instance and thus no implicit this reference. Class methods can
always be used, even if you have no instance of the class on hand.
Class methods, like class variables, are declared with the static
keyword.
For example, the currentThread
method in class Thread is a class method. You invoke
it on the Thread class itself, and it determines the
currently executing thread and returns a reference to it.
Thread activeThread = Thread.currentThread();
As
alternates to the names instance variable, instance method, class
variable, and class method, some Java programmers prefer to use
terms such as member, field, static field, method, and static
method. Table 1.2 summarizes how the various terms are related.
Table 1.2:
Names for Elements in a Class
| member |
field |
instance
variable (or nonstatic field) |
| class variable
(or static field) |
| method |
instance
method (or nonstatic method) |
| class method
(or static method) |
Note: The
term field is useful for distinguishing variables defined
in a class, as opposed to local variables, which are defined
inside a method.
|
|
Q . How do I create an instance of a class?
|
Ans
:
The usual
way to create a class instance is to invoke a constructor for the
class.
In
Java, all objects (class instances and arrays) are created with
space allocated from system-managed memory, but you never access
that heap directly. The Java language and Virtual Machine manage
it for you via the new keyword, the newInstance
method in class Class, and automatic garbage
collection.
The standard way to create a class
instance is with the new keyword followed by the name of the class
and arguments for one of the class's constructors. For example:
Button myButton = new Button("Press Me");
This line of code
declares a variable named myButton, creates a new Button
instance labeled Press Me, and sets the myButton
variable to refer to that button. Common coding style in Java is
to declare a class-type variable and initialize it to point to a
newly created instance all in the same line of code.
For comparison, if you simply
declare an instance variable of type Button, as in:
Button myButton;
then all you've
created is a variable named myButton initialized with
a null reference (by default initialization). Or if you declare a
local variable (that is, a method-internal variable) as above, the
compiler will require you to set it to some value before you can
use it.
You can also create or obtain class
instances by invoking methods. Some methods always return a new
instance, such as the newInstance method in class Class
and the valueOf method in class Integer.
Other methods, such as InetAddress's getByName
method, may return an instance, but without any guarantee that the
instance is distinct from others it returned earlier.
|
|
Q . What is an abstract method?
|
Ans
:
An abstract
method is a method that defines all aspects of itself except what
code it executes.
An
abstract method declares the method's name, parameter types,
return type, and exceptions, but does not provide an
implementation for the method. You declare an abstract method with
the abstract keyword and with a semicolon in place of
the method body. For example:
public abstract void drawFigure(); // abstract method declaration
Abstract
methods let you design a class with some or all pieces left for
subclasses to fill in. A class containing abstract methods is also
called abstract, and must also be declared with the abstract
keyword. By including an abstract method in a class,
you require that anyone who implements a fully functional (concrete)
subclass will have to include an implementation for that
method.
For example, the Number
class in the java.lang package consists entirely of
abstract methods. The full JDK (1.0.2 and 1.1) class definition
is:
/* in Number.java (JDK 1.0.2 and 1.1): */
public abstract class Number {
public abstract int intValue();
public abstract long longValue();
public abstract float floatValue();
public abstract double doubleValue();
}
The java.lang
package also contains several concrete subclasses of Number:
Integer, Long, Float, Double,
and (starting with the JDK 1.1) Byte and Short.
Each of these subclasses defines implementations for the four
abstract methods just listed.
As another example, the InputStream
class in the java.io package provides the base for a
large family of subclasses that handle specific types of
byte-oriented input streams. The JDK 1.0.2 class definition
implements all its methods except one. (In the JDK 1.1, InputStream's
available method is also defined as abstract.) The core
no-parameter read method, responsible for reading one
byte of input, is left abstract so that subclasses must define it:
public abstract int read() throws IOException;
The other read
methods in InputStream are defined to eventually
result in calls to read(). In this way, when you
implement read() in a subclass, the rest of the class
is already integrated around your new method definition.
|
|
Q . What is an abstract class?
|
Ans
:
An abstract
class is a class designed with implementation gaps for subclasses
to fill in.
An
abstract class is deliberately incomplete. It defines a skeleton
that various subclasses can flesh out with customized
implementation details. The different concrete (nonabstract)
subclasses provide a family of variants.
An abstract class must be explicitly
declared with the abstract keyword. Note that
declaring a class as abstract suffices to make it abstract—it
need not even have any abstract methods. By declaring it abstract,
you signal that it is functionally incomplete, and you ensure that
no one can create instances of that class.
The AWT Component
class, for example, is the abstract superclass for all AWT
user-interface elements. Although it provides default
implementations for all its methods, it is nevertheless declared
abstract. Component is not meant to be instantiated
directly. Instead, it provides a common infrastructure within
which more specific subclasses, such as Button and TextField,
can be defined and instantiated.
|
|
Q . What does it mean that a method or class is abstract?
|
Ans
:
An abstract class cannot be instantiated. Only its subclasses can be instantiated. You indicate that a class is abstract with the abstract keyword like this:
public abstract class Container extends Component {
Abstract classes may contain abstract methods. A method declared abstract is not actually implemented in the current class. It exists only to be overridden in subclasses. It has no body. For example,
public abstract float price();
Abstract methods may only be included in abstract classes. However, an abstract class is not required to have any abstract methods, though most of them do.
Each subclass of an abstract class must override the abstract methods of its superclasses or itself be declared abstract.
|
|
Q .
What is an object reference?
|
Ans
:
An object
reference is essentially an object pointer with strong
restrictions for integrity and safety.
As
a Java programmer, you can access objects (class instances and
arrays) only by means of object references. Behind the scenes, an
object reference provides two kinds of information to the run-time
system:
- a pointer to the
object's instance information—its data
- a pointer to the
object's class information—its run-time type and its table
of methods
Although
pointers exist inside the Java run-time system, you cannot
manipulate them directly. The Java language does not expose a
numerical notion of references or pointers: you cannot do pointer
arithmetic, nor can you fabricate pointers from numeric data.
The operations you can perform on an
object reference all treat the reference as an opaque entity.
Table 1.3, adapted from The Java Language Specification
(p. 39), summarizes the possible operations on an object
reference:
Table 1.3:
Possible Operations on an Object Reference
| assign the
reference to a variable |
| invoke a
method on the reference |
| extract a
field from the reference |
| cast the
reference to another type |
test the
reference's run-time type using the instanceof
operator |
| concatenate
the reference with a String instance |
| test the
reference for equality with another reference using == and
!= |
| provide the
reference as a value in the conditional operator ?: |
The integrity of
object references in Java is a cornerstone of security (protection
from malice) and safety (protection from mistakes).
As an example, consider the
following code fragment:
String s1;
String s2;
s1 = "a string";
s2 = s1;
The first two lines
declare two String variables; at this stage, s1
and s2 are simply uninitialized local variables. The
third line sets s1 to refer to the String
instance represented by the string literal "a string".
The fourth line sets s2 to refer to the same object
as s1. There is still just one String
instance, but now two separate references to it.
When you declare a variable of a
class, interface, or array type, the value of that variable is
always an object reference or the null reference. The
following chart compares similar definitions in Java and C++:
| Java |
C++ |
Button
b: |
Button
*b: |
String
s: |
String
*s: |
|
|
Q . What are "class literals"?
|
Ans
:
A feature introduced in JDK 1.1. They are literals of type "Class"
that hold a value representing any class. There are even values to
represent "void" and an array, like this:
Class myCl1 = Character.class;
Class myCl2 = Void.class;
Class myCl3 = Object.class;
Class myCl4 = String[].class;
Class myCl5 = int[][].class;
You might use it like this:
Class cl = thing.getClass();
if (cl.equals(myCl1))
System.out.println("It's a Character class");
Note that a class literal
Component.class
is the equivalent of
Class.forName("java.awt.Component")
The second can throw an exception, but the first cannot. If you don't know the name of the class when you write the code, you cannot use the
first form.
|
|
Q . How can I find the format of a .class file/any file?
|
Ans
: There is a great website that maintains descriptions and links to
descriptions of hundreds of file formats. The site is at: http://www.wotsit.org/
It shows you how the files are structured, and makes it a lot simpler
for you to write code that creates/decodes such a file.
|
|
Q . Where can I find examples of the use of the Java class libraries?
|
Ans
:
The two volumes of "Java Class Libraries" by Chan, Lee and Krama
published by Addison Wesley, have extensive examples of how to use the
standard libraries. One programmer comments "When I need to use an
unfamiliar area of the class libraries one of the first things I do is
read their examples." You can see them online at http://java.sun.com/docs/books/chanlee/second_edition/vol1/examples.html
and http://java.sun.com/docs/books/chanlee/second_edition/examples.html
|
|
Q .
How do static methods interact with inheritance?
|
Ans
:
Static (per-class, rather than per-object) methods do not
participate in overriding (choosing the right method at runtime based
on the class of the object). Probably the best and simplest way to
think about this (and to write your code) is to write every invocation
of a static method using the fully qualified class name:
class A {
public static method1() {
A.method2();
}
public static method2() {
}
}
class B extends A {
public static method3() {
A.method1();
}
public static method2() {
}
}
Now it is perfectly clear that the static method2() that is called is A.method2(), not B.method2(). A.method2() will be called regardless of
whether you use the fully-qualified class name or not, but using "A."
makes it obvious to all.
|
|
Q . Why is the String class final? I often want to override it.
|
Ans
:
Being final guarantees that instances of String are read-only. (The
String class implements read-only objects, but if it were not final it
would be possible to write a subclass of String which permitted
instances to be changed.) Strings need to be read-only for security and efficiency.
As for efficiency, Strings are very commonly used, even behind the scenes by the Java compiler. Efficiency gains in the String class yield
big dividends. If no one can change a String, then you never have to
worry about who else has a reference to your String. It's easier to
optimize accesses to an object that is known to be unchanging.
Security is a more compelling reason. Before String was changed to be final (while Java 1.0 was still in beta) there was a race condition
which could be used to subvert security restrictions. It had to do with
one thread changing a pathname to a file after another thread had checked that the access was permitted and was about to open it.
There are other ways to solve these problems, but the designers preferred making String final, particularly since the StringBuffer
class is available as an alternative.
|
|
Q . How can I safely store particular types in general containers?
|
Ans
:
I often want to store particular types of objects but don't want to
subclass my basic storage classes to enforce the particular type; that
would make for too many subclasses (e.g., IntegerLinkedList,
StringLinkedList, etc.).
Generic programming in java (the rough equivalent of C++'s templates) works reasonably well since all java classes are subclasses
of Object. There is, however one potential problem - there is always a
possibility that a generic container may contain different classes of objects.
This naturally leads to the question of how to do this in a type-safe way. If you've created a generic LinkedList class, how can you be type
safe without having to create a multitude of subclasses
(IntegerLinkedList, StringLinkedList, etc.)?
One way to handle this would be to offer up an additional constructor in your generic class that takes a parameter of type "Class" and uses
that parameter along with Class's "isInstance" method to guarantee that
Objects added to the container are the expected type.
public class LinkedList {
Protected Class type = Object.class;
public LinkedList(Class type) { this.type = type; }
public void addElement(Object element) throws Exception
{
if(!type.isInstance( element ))
throw new Exception(
"Expected element of type (" + type + ")" +
" got element of type (" + element + ")" );
...
}
}
Note that the comments in the source for isInstance() refer to a "specified Class parameter", suggesting that you are supposed to write
something like:
public void addElement(Object element) throws Exception
{
Class c = element.getClass();
if(!type.isInstance(c))
This works, but the documentation for isInstance is clear that the parameter should be an Object rather than a Class. Also, note that
"Collections" are coming in JDK 1.2, and they provide a much safer and
more extensible mechanism. More information about this is available at the Java Developer Connection at the Java website:
http://java.sun.com/
|
|
Q . I can't seem to change the value of an Integer object once created.
|
Ans
:
Correct. Integer (Float, Double, etc) are intended as an object
wrapper for a specific value of a number, not as a general-purpose way
of shipping a primitive variable around as an Object. If you need that
it's easy enough to create: class General { public int i; }
|
|
|
|