In this chapter, you will learn all about Java classes. Classes form OOP's foundation. in this chapter, you'll gain an insight into object-oriented programming with Java. If you are a C++ programmer, you'll feel at home here except Java does provide some special OOP features (and limitations) you'll not find in C++.
Most of your Java programming revolves around a class's data and methods. Java contains all kinds of rules and conventions for specifying class data and methods. In this chapter, you'll finally understand how methods perform their work and you'll see how to set up data that respond to those methods.
A class is often synonymous with a Visual J++ applet. A Java program usually consists of a single class definition. Classes exist for objects that you define. Although I've thrown around the term object throughout this book, I've never really defined the term. An object as like a variable except that an object is active whereas a variable is passive. A variable has a data type and holds a value. An object not only can hold data, but the object can hold data of several different types of data. Often, an object's data values are called data members. In addition to data members (sometimes called fields), objects also contain methods.
Think about that last sentence. A method, as you already know, is set of code lines similar to a procedure. Methods belong to classes. When you write a class, you not only describe the data within the class but you also describe the class abilities by including methods in the class.
Let's return once again to chapter 9's sample program. Listing 12.1 contains the code that you studied in chapter 9. Whereas chapter 9 approached the code form a micro-explanatory viewpoint (line-by-line), we'll now look at the listing using a class perspective.
Listing 12.1 Analyzing a Program's Class
//*******************************************************************
// Simple.java: Applet
//*******************************************************************
import java.applet.*; // Requires support files
import java.awt.*;
//===================================================================
// Main Class for Simple applet
//===================================================================
public class Simple extends Applet
{
public void init()
{
resize(320, 240); // applet's window size
}
//--------------------------------------------------------------
public void paint(Graphics g)
{
// Change subsequent text color to red
g.setColor(Color.red);
// Write a simple message in the window
g.drawString("Very simple!", 75, 100);
}
}
Although the Simple applet contains several statements, all of those statements reside in a class named Simple. The Simple class happens not to contain data; as you can see, no variables are defined because all of the data consists of literal data values. Nevertheless, you could define integers, characters, and variables of all the other data types within the Simple class. If you did define variables, the variables would be part of the Simple class. When the Web page that contains this applet executes the compiled bytecode, one object, the Simple object, is created. In OOP terminology, when you or your computer creates an object, the object is instantiated (Never use a small word when a huge one will confuse lots of people!).
The Simple object can do two things that a variable could never do: initialize itself and paint itself on the screen. The Simple object that Java instantiates can perform these two actions. In addition, once you define a class such as Simple, you can create additional classes that inherit all of Simple's definition and actions and you can also extend the capabilities of that inherited object.
An object is actually a data item but an object is a full-packaged data item with active methods and usually data fields. Generally, in an OOP language such as Java, anything you can do with variables, you can do with objects. Therefore, you can define objects (through class definitions), create (instantiate) objects, assign data to objects, and even perform calculations with objects. Unlike the built-in data types such as int and double, if you perform a math operation on one of your objects, you'll have to teach Java how to do the math by writing a method that performs the work. Once you supply the method's code once, however, calculating with the objects is basically as easy to do as calculating with the built-in types.
You define variables but you instantiate objects. Listing 12.2 helps clarify the difference.
Listing 12.2 Instantiating Objects
//*******************************************************************
// The Box class
//===================================================================
class Box // No inheritance
{
float area; // A class data member
int colorCode; // A class data member
void calcArea (float width, float length)
{
area = width * length;
}
void setColor (int colorValue)
{
colorCode = colorValue;
}
}
Box is a class with four members: Two of Box's members are data members and two are methods. Box is not an object! You can, however, instantiate objects from the Box class.
In a way, a class works almost like a new data type that you add to the Java language. Java does not need to be told what an int is before you define an int variable like this:
int value; // This statement defines a new int variable named value
Java, however, does not know what Box is. Only until you define the Box class, as in listing 12.2, can you then define, or more accurately instantiate, a Box object:
Box hatHolder; // This statement defines a new Box object named hatHolder
Can you see that, loosely speaking, an object is a lot like a variable? You first have to tell Java about the object's type by defining the object's class, and you then have to define one or more objects just as you can define one or more variables. Unlike a variable, however, the hatHolder object contains more than a single data type; hatHolder is a combination int and float value, along with two methods that manipulate the data values.
After instantiating an object, execute that object's methods with the dot operator. The following statement executes hatHolder's calcArea() method:
hatHolder.calcArea(4.3, 10.244); // Executes the calcArea() method
In chapter 10, "Java Language Fundamentals," you learned how to use the new keyword to define an array. new also defines objects. Due to special object-constructing considerations that you'll learn about later in this chapter (see "Special Constructor Methods"), get into the habit now of defining objects using new instead of defining them with the simpler className objectName; format. Here is how you would define, or instantiate, a Box object using new:
Box hatHolder = new Box(); // This statement instantiates a new Box object
Always use the parentheses when you use new with object instantiation. You can instantiate two Box objects like this:
Box slot1 = new Box();
Box slot2 = new Box();
You now can calculate the area for the second Box object like this:
slot2.calcArea(1.0, 5.0); // Sets the second object's area
You can specify the color for the first box like this:
slot1.setColor( 4 ); // Sets the first object's color
The data members are not always available to the outside world. One of OOP's strengths is data hiding, or limiting the access of data members to classes and methods outside the current class. Although you can provide a way for data members to be fully available to outside code (as you'll see later in the section entitled, "Data Member Modifiers,") this chapter will assume that all data members are hidden from access by any code outside the current class.
Therefore, if an outside class or a derived subclass is to instantiate a Box object, that class cannot generally access the data members colorCode and area directly; the methods, however, do allow code to access and even initialize the data members, but only through the method's code. Suppose you don't want someone changing the color of a box unless they know a password. You can add the password-checking code at the beginning of the setColor() method. Only code that sends the correct password can then change the color because the color data member is completely unavailable to code outside the Box class's method area.
If you need to define an array of objects, you can do so like this:
Box hatHolders[] = new Box[50];
The array named hatHolders contains the elements hatHolders[0] to hatHolders[49].
To execute one of the array's methods, specify the array element and then the method:
hatHolder[2].setColor(12); // Sets the color for the 3rd Box object to 12
If you inherit a class from Box, all objects of the inherited class will also contain the original Box class's two data and two method members. You can add additional data and method members to the subclasses if you want inherited objects to gain more functionality than the Box parent class provides alone.
In addition to inheritance, you can use a class or a package of classes from other classes. You saw how to simulate inheritance in part II," Taking Visual J++ to Task," by specifying new parameter values, although you did not yet have enough background necessary to understand full inheritance concepts at the time.
The Simple class's init() and paint() methods are not new methods! You are extending methods already given to you. At this point, you cannot tell if the methods came from Applet's methods or one of the imported classes.
Often, a class's data members and method members are called instance variables and instance methods because the data and methods really don't exist (they are only described) until you instantiate an object.
Where Are We Going with All This?
A class falls into one of the following types:
You're responsible for defining and naming your own classes. A class name follows the identifier naming rules, so when naming a class follow the same guidelines as you use when naming variables.
When you define a public class, you make that class available to any and all classes that might want to inherit from the class. In part II, you extended many public classes and you were able to change the way a program worked simply by specifying parameter values. You can also extend a public class and add to the behavior of that class.
The public keyword defines a class to be public. Therefore, listing 12.1's Simple class (the child class of Applet that's supplied with Visual J++) is public due to the class definition line shown here:
public class Simple extends Applet
You don't have to inherit a class to create a class. The following statement defines a class named MyClass that is not a subclass of any other class because the definition does not include the extends keyword:
public class MyClass // The class body would follow
Instead of public, if you define a class to be final with the final keyword, no code can inherit the class. Security concerns generally require that some classes, such as password classes, network-based classes, and file-encryption classes, remain protected from any later inheritance.
The following statement defines a final class named Secure:
final class Secure
An abstract class is an incomplete class. The class contains at least one method but the method contains no code. Although you cannot instantiate objects from abstract classes, you can inherit from an abstract class and fill in the missing pieces in the inherited class.
For example, you could create an abstract printing routine that will eventually, in inherited classes, print output on different kinds of printers. You could include an unfinished colorPrint() method. If you then inherit the class for a specific color printer, the inherited class could fill in the colorPrint() method with colorized output. If you inherited the class for a black-and-white printer, you could fill in the colorPrint() method that produces only black-and-white colors. You'll still retain all the functionality of the parent class, however, as long as you fill in the missing pieces and extend whatever data fields and methods needed by inherited objects.
The following statement defines an abstract class:
abstract class printArt
A friendly class contains no public, final, or abstract keyword. The following statement defines a friendly class:
class Casper // Defines a friendly class
The friendly class makes its data fields and methods available to all other classes that want to inherit as long as those classes reside in the same package as the friendly class. In other words, the friendly class is lenient about giving its inheritance away but only to other members of the same class package.
Methods do the work of classes. Therefore, you should take a few moments to learn about methods before continuing your class tutorial.
Although you've seen methods in action, and although you know a little about what methods are all about (detours from code you call or class procedures that you write that activate the class objects), this section explains methods in a little more detail and fills in a few more pieces of the method puzzle.
Methods perform work. Methods operate on class data by using the controlling statements you learned about in the previous chapter and also by utilizing variables that you declare along the way. In the previous chapter, you learned that a method's parameter list may contain values or the list may be empty. If parameters exist, the code that calls the method must initialize those values and send the expected parameter number and data types.
Figure 12.1 shows how the code in one method calls another method and sends that called method two parameters. Java sends a copy of the parameter values but does not really send the parameter variables themselves. Therefore, if the called method changes a parameter in any way, the change is not noticed when the calling code regains control.
The calling code sends two expected parameters to the called code.
Notice that Java passes the values and not the variables to the receiving method. The method takes the two values, computes with them, prints their newly-computed values, and then returns control to the calling class.
Here is the output from figure 12.1's code:
In method...
a=456.000
b=4608.294930876
In calling class...
a=10.0
b=20.0
As you can see, the called method receives two values and changes those values but the changes last only inside the method. The calling class code's variables are not, and cannot, be changed by the method.
The return statement does not have to appear at the end of this called method because the method does not return any values to the calling class program. Without the return, program control would still return to the calling class once the method finishes.
The method's parameters are named x and y even though the calling program names those variables a and b. The received names might or might not match those in the calling code because only values are passed not variables. The biggest concern you must make when passing data to methods is to get the number of parameters and data types correct. The method is expecting a float followed by a double as you can see from the method's definition line shown below:
void myMethod(float x, double y)
The calling code must provide two variables that match this pattern. The first definition line of a called method must always define the parameters and their data types.
The passing of data between code and methods is not strictly one-way. A method can return a value to the calling code. Although you can send zero, one, or multiple parameters to a method, you can return only a single value. Figure 12.2 illustrates the return nature of methods.
A called method can return only a single value.
Here is the output from figure 12.2's program:
In calling class...
a=10.0
doub=20.0
The doubleIt() method is a two-way method in that the calling code passes a parameter and the method also returns a value back to the calling code. The called method does not change any value in the calling code; the called method does, however, use the passed value, doubles the value, and returns the doubled value back to the calling code. The calling code captures the return value in the variable named doub.
The float in front of the doubleIt() method's definition line describes the method's return value. Although you can pass zero, one, or more parameters to a method, you can return only one. Therefore, a method always has at most one data type listed to the left of the method name. When you write your own methods that your class code will call, you'll want to include the method's returndata type in front of the method name as well.
Look back at figure 12.1's myMethod() definition line. You'll see the void keyword. void is a method modifier that indicates no return value will be coming from the method to back to the calling code. Therefore, the first word before a method's name, in the method's definition line, describes either the returned value's data type or void if no return value exists.
If a method does not require parameters, leave the parameter list empty. Unlike C and C++, you don't include the void keyword in a method's parameter list when no parameters are expected. A method definition's empty parameter list indicates that you are to pass no data to that method.
Receiving the Returned Value
A method may or may not be available to classes that inherit from the method's original class. Through the following access modifiers (sometimes called specifiers) that define how an inherited class can use a method, you can limit or supply access to subsequent child classes:
A class might contain several methods. Within the class, all methods can access (call) the other methods within the class. Derived classes, however, cannot and should not always be able to access all methods as freely as the class's original brother and sister methods.
To understand why, you should know that a class's data members are not always available to the outside world including classes that derive from that class and to methods that use that class. Suppose you write a security class that holds a network password in a string data member. You don't want other classes to be able to see or change the string except under strict circumstances. You can specify those circumstances by writing a class method that returns the password only when a user has access to see the password. In other words, derived classes cannot access the password data member but derived classes can access a method that returns the password if the user enters the correct permission.
You'll need to specify method access availability whenever a method handles critical data. The following sections briefly introduce you to the access specifiers and explain when and where you can use them.
When you place the public keyword in front of a method's definition line (before the return data type), the method is accessible to any and all derived methods. In addition, the method is also available to any program that uses the method's class.
The following statement defines a public method:
public float freeMethod(int x, float y, char z)
A protected method behaves exactly like public methods with one limitation: Objects that reside outside the protected method's package, that is, objects that you instantiate from classes outside the protected method's class package, have no access to the method.
The following statement defines a protected method:
protected float freeMethod(int x, float y, char z)
When you want to restrict a method's access only to the class in which you define the method, use the private access specifier. A method is not always a general-purpose method such as the one described in the section named "A Method's Execution." Sometimes, you'll write a helper method that supports other methods within the class, perhaps to encrypt or decrypt a password, but you don't want any class, derived or otherwise, to use the method. That method is best left private; therefore, only the other class methods have access because they are the only ones with a need to know about the method.
The following statement defines a private method:
private float freeMethod(int x, float y, char z)
A friendly method occurs when you forget to put a method's access specifier, or when you choose to omit the access specifier. Friendly methods are available to all other methods and classes within the package in which you define the friendly method. However, derived classes cannot access a friendly method.
There is no friendly keyword. A method automatically friendly if you do not use any other access specifier. The following statement defines a friendly method:
float freeMethod(int x, float y, char z)
A private protected method makes itself available only to derived subclasses. That is, a private protected method is usable from derived classes but no other class in the package or in an outside package can use the method.
The following statement defines a private protected method:
private protected float freeMethod(int x, float y, char z)
An abstract method contains no code. By using the abstract keyword, you designate a method as an abstract method, and therefore, you designate the class as abstract as well. Consider the following method:
abstract float freeMethod(int x, float y, char z);
Look at the last character on the line! The semicolon does not appear in the other method definitions you've seen! The semicolon terminates the method right there. The method has no body because it's an abstract method. It is now incumbent upon a derived class to supply an overriding method, with a coded body, to turn this abstract method into a functioning derived method.
To understand a static method, you must understand a static data member. Suppose you defined a data member to be static as done in listing 12.3. Listing 12.3 looks like listing 12.2 except for the static data member and method.
Listing 12.3 Using a Static Member and Method
//*******************************************************************
// The Box class with a static member and method
//===================================================================
class Box // No inheritance
{
float area; // A class data member
static int colorCode; // A class data member
void calcArea (float width, float length)
{
area = width * length;
}
static void setColor (int colorValue)
{
colorCode = colorValue;
}
}
A static data member exists once no matter how many instance variables, or objects, you instantiate. Therefore, if you were to define an array of 100 Box objects, then set the static colorCode variable to 5, all 100 objects would have a colorCode value of 5. A static data member exists once. You create the static data member the first time you create an object. Thereafter, all objects contain that same static member.
With a static data member, one Box object cannot have a different colorCode value from another Box object. They all have the same colorCode value. A static method can work only with static data members. Therefore, if you want to allow your user a chance to set the color for all boxes, no matter how many Box objects have been or will additionally be instantiated, you could write the following code that asks the user for a color code value and sets the color for all instantiated Box objects that exist:
Int userColorCode;
System.out.print("What color code do you want for all the boxes?");
System.in.read(userColorCode); // The user types the code
hatHolder.setColor(userColorCode); // Set the user's color to all boxes
As long as you use one instantiated object to set the static data member, all the other objects will get the member. Remember that code cannot usually change an object's data member values directly, but methods can. The static method changes every static data member instantiated. If you then instantiate additional Box objects later in the program, those objects will also contain the same colorCode set for the current objects.
By defining a method with the final keyword, you disallow a subclass from overriding the method with a new derived method. In other words, the parent class's method version will be sure to exist in all child classes, even if the child classes contain the same method name. If a child object triggers the method, the parent's method will execute and not the method defined (incorrectly) inside the child's class.
The following statement defines a final method:
final float freeMethod(int x, float y, char z)
Native methods are methods that you write in C++, not Java! By defining a method as native, as shown here:
native float freeMethod(int x, float y, char z);
you tell Visual J++ that the method exists in C++ and you'll supply that method later.
The semicolon at the end of the native method definition tells Visual J++ that this method does not contain any Java code so Visual J++ will not look for Java code within the native method's body.
When you program in Java's threaded mode (where two or more threads, or program logic flows execute in parallel with each other), you should write synchronized methods for those methods that might attempt to access the same data at the same time.
For example, suppose that one method sets a boolean data member to true and another method prints an hourly report only if the first boolean data member is set to true. If you were to set up these methods without synchronizing them, the hourly check could execute right as the other method sets the boolean value to true. One of two results could occur:
The hourly report printing could be too critical to leave to chance. If you add the synchronized keyword before both methods, the methods will never execute at the same time and would always produce consistent results.
The following statement defines a synchronized method:
synchronized float freeMethod(int x, float y, char z)
Two or more methods can have the same name and yet, Visual J++ has no trouble compiling the code and knowing which method you want to execute. The trick is to change the parameter list in the methods. The overloaded methods must either have a different number of parameters or the parameter data types must differ.
Visual J++ considers these four method definitions to be different because the four methods are properly overloaded:
int overloaded(float x, char y)
int overloaded(float x)
int overloaded(int x, char y)
int overloaded()
Suppose you want to write a method that computes and returns the square root of its parameter. If you want the square root method to be general-purpose, the method should be able to handle whatever data type you pass to it. Without overloading, however, you would have to tediously write a separate method for each data type. Worse, however, is that you would have to call the correct method depending on the data type of the value you want the square of. Therefore, you might be faced with a situation of calling one of the following methods depending on the data type of the argument:
byte squareByte(byte p)
int squareInt(int p)
short squareShort(short p)
long squareLong(long p)
float squareFloat(float p)
double squareDouble(double p)
Surely you get the idea. Such classes would consume a terrible amount of your time and bugs could easily enter your program because you may not call the appropriate method for the data type you're passing. With overloading, you'll still need to write separate methods for each data type but you can give each function the same name as done in the following method definitions:
byte square(byte p)
int square(int p)
short square(short p)
long square(long p)
float square(float p)
double square(double p)
You now never have to worry about calling the correct method! If you have a byte variable, you'll find the byte variable's square root like this:
ans = square(myByteVar); // Passes a byte variable to the correct method
If you need to get the square of a variable defined with the double data type, you would find the double variable's square root like this:
ans = square(myDoubVar); // Passes a double variable to the correct method
Constructors are special methods that initialize an object's data members. If you've supplied a constructor for a class, the Visual J++ compiler ensures that the constructor method executes every time you create a new instance of the object. That is, every time you instantiate a new object, whose class contains a constructor, the constructor automatically executes.
You don't call a constructor method directly. The constructor executes on its own. A class method is a constructor as long as you define the method with these two rules:
If you define a class named Box, the following method would define Box's constructor method:
void Box()
Due to overloading, you can define multiple constructors. All of the following methods could be Box constructor methods within the same class:
void Box() // Default constructor
{} // No initialization takes place
void Box(float a)
{
area = a; // Initializes the area data member but not the color
}
void Box(int c)
{
colorCode = c; // Initializes the color but not the area
}
void Box(float a, int c)
{
area = a; // Initializes both data members
colorCode = c;
}
Such overloaded constructors might appear in your applet to offer several initializations for Box objects. As you'll recall from earlier in this chapter, an object's data members generally are not available to code outside the class. Therefore, if your applet defines an object from an imported class, your applet probably cannot initialize that object's data members directly.
The constructors give you several options you can use to define the data members of the Box objects you define. Suppose you want to instantiate a Box object but you don't yet know the values for the object's data members. Your applet could define the object like this:
Box aBox = new Box(); // No data members are initialized
To initialize the data members (assuming the members are unavailable as they usually are), you would have to call additional methods that initialize the data members once you learn the values. The constructor that takes no parameters, by the way, is called the default constructor.
Later in the same applet, you want to initialize a Box object and you know the color code you want that object to have at the time you define the object. If you called the second constructor like this:
Box blueBox = new Box(28.75); // A new object with its area definedc1
Java creates an object named blueBox and the area data member contains the value 28.75. As you can see, the parameter (or parameters) that you supply determines which constructor executes and also determines which data members get initialized. The constructor you decide to call in your program depends on how much initialization information you know when you instantiate your objects.
Default Constructors Call Parent Constructors
As with classes and methods, you can modify the access rights to data members as well. You can modify the access to data using the following data access modifiers:
When you define a class's data member as public, any code that uses the class can directly access and modify the data member. You could define the Box class's area data member like this:
public float area; // Available to all!
The public area data member is visible and available to any class, subclass, or method that uses Box objects.
When you define a class's data member as protected, only derived subclasses and other classes within the current class package can access the data member. No other code outside the class or outside a derived class can directly access or modify the protected data member. You could define the Box class's area data member like this:
protected float area; // Available only to this package's class and subclasses
Protected data members are safer than public members because only classes defined to access the data members can access the data. All other code must use the Box class's (or Box's derived class's) methods to view or change area.
When you define a class's data member as private, only the current class can access or change the data member. Not even derived classes can access the private member.
You could define the Box class's private area data member like this:
private float area; // Available only to THIS class
You define a class's data member as friendly when you don't use any other access modifier. The following statement defines the area data member as friendly because no other modifier appears:
float area; // A friendly modifier exists here
Only classes within this class's package can access or modify the friendly area. Derived subclasses do not have access so someone cannot derive a new class and expect to have access to the data.
When you define a data member as a private protected data member, that data is accessible only to the class and to all derived subclasses. You could define the Box class's private area data member like this:
private protected float area; // Available only to this class and subclasses
As you learned earlier in this chapter, a static data member exists only once. No matter how many data objects you instantiate, a static data member exists only once and is the same for every object.
When you define a data member as a final data member, that data is no longer a variable data member! The data member instantly becomes a named constant. A named constant is a named variable that's fixed to a specific value for the life of the final variable.
You must always specify the final value when you define a final data member. The following statement defines a final data member:
final float PI = 3.14159; // Unchanging!
Any code that uses this final variable's class can refer to PI but cannot change PI. PI is a fixed variable and its value can never change. Use named constants for mathematical constants (such as PI and e) as well as other literals that you'll use throughout a class. The named constant eases subsequent program maintenance because you don't have to remember what you're using a numeric literal for; the name can offer a clue as to the literal's use.
A variable's scope refers to that variable's life or availability within code. When you define a variable, that variable exists only for the block in which it's defined. Therefore, x is not available to the second System.out.println method here:
{ // Starts a new block
int x = 14; // "Local" to this block
System.out.println("x is equal to " + x);
} // x goes completely away
{ // Starts a new block
System.out.println("x is equal to " + x); // Error!
}
Not only will the second System.out.println() method not be able to print x, but Visual J++ will not even compile this program! Visual J++ knows that x is outside the scope of the second block so the second block cannot be expected to print the value of a variable that does not exist.
An applet can even contain two variables with the same name as long as you define both variables in different blocks. Although two variables with exact names often makes for confusing debugging sessions, such variables are great for loop counters as in the following:
{ int loopCtr;
System.out.println("Even numbers below 20:");
for (loopCtr = 2; loopCtr <= 20; loopCtr+=2) // Adds 2 each iteration
{ System.out.println(loopCtr); }
}
// Later in the applet, perhaps in a different method
{ int loopCtr; // Same name, no conflict
System.out.println("Odd numbers below 20:");
for (loopCtr = 1; loopCtr <= 20; loopCtr+=2) // Adds 2 each iteration
{ System.out.println(loopCtr); }
}
When you define a data member (an instance variable), that data member exists for every method throughout the entire class, not just in a single block.
The this variable lets a class refer to itself. Suppose you create a class with a data member and also include a method that has the same data member name. Although such name duplications are not recommended, some applets make sense to have them. When the method refers to its own data member, you can refer just to the method's data member name. However, when the method needs to refer to the class's data member, use this to scope the data member to the class's data member. In this situation, value would be the method's data member and this.value would be the class's.
The super variable refers to the most recent parent class. Therefore, if you want to refer to a parent class's data member or execute a parent class's method, because the subclass contains more functionality than you want, precede the data or method with super. Therefore, super.value refers to the current class's parent version of value.
These two special variables will make more sense as you continue to grow your OOP skills and come upon programs that require this and super.
The goal of this chapter was to teach you the basics of object-oriented programming. Now that you've completed the chapter, you should have a much better idea what classes, methods, and data are all about. The new operator creates the class objects that your program can use. An object is much more than just a variable that holds data; objects contains methods so objects are active.
The next chapter starts a new section of this book. You will learn all about the built-in methods that Visual J++ provides. You will also see how to implement much of the OOP-related features that you learned here.
Here are the points this chapter covered:
| Previous Chapter | Next Chapter |
| Table of Contents | Book Home Page |
| Que Home Page | Digital Bookshelf | Disclaimer |
To order books from QUE, call us at 800-716-0044 or 317-361-5400.
For comments or technical support for our books and software, select Talk to Us.
© 1996, QUE Corporation, an imprint of Macmillan Publishing USA, a Simon and Schuster Company.