Richard G Baldwin (512) 223-4758, baldwin@austin.cc.tx.us, http://www2.austin.cc.tx.us/baldwin/

Classes

Java Programming, Lecture Notes # 38, Revised 10/01/99

Preface
Introduction
The Creation of Classes
The Class Declaration
Declaring the Superclass of a Class
Identifying Interfaces Implemented by a Class
The Body of the Class
Review

Preface

Students in Prof. Baldwin's Introductory Java Programming classes at ACC are responsible for knowing and understanding all of the material in this lesson (except that they are not responsible for detailed information that is specific to C++).

The detailed material on C++ is provided as supplementary material for the benefit of persons already familiar with C++ and who are making the transition into Java.

Introduction

An object is an instance of a class.

All variables and functions in Java must be contained in a class or an object.

Three primary characteristics of an object-oriented programming language are:

The class is the central concept of Java that supports encapsulation.

The class provides the plan from which objects are built. This plan defines the data that is to be stored in an object, and the methods for manipulating that data.

The data is variously referred to as data members, fields, and variables, depending on which book you are reading.

The data can be sub-divided further into static or non-static, often referred also as class variables and instance variables respectively.

The methods are also often referred to as member functions, and can be static or non-static.

Static methods are often referred to as class methods while non-static methods are often referred to as instance methods.

We say that objects instantiated from a class have state and behavior.

The current state of an object is determined by the current values of its variables and its behavior is defined by its methods.

The Creation of Classes

The definition of a class deals with two parts: declaration and body using the general syntax shown below.

classDeclaration{
  classBody
}

.

C++ programmers should note that the closing curly brace in a class definition is not followed by a semicolon as is the case in C++.

The declaration notifies the compiler of the name of the class, and also can provide other information such as

The class body contains the declarations for, and possibly the initialization of, all data members (both class variables and instance variables) as well as the full definition of all methods.

C++ programmers should note that unlike C++, the full definition of all methods (both class methods and instance methods) must appear inside the class definition, and this does not make them inline methods. The concept of an inline method is not supported by Java.

Variables may be declared either

(Variables can also be declared in the formal argument list of methods and in the argument list of exception handlers. We will have more to say about this later.)

Note that variables that are declared inside the body of a method are not member variables of the class. Rather, they are local variables in the method.

Therefore, we could expand our general syntax diagram to be as shown below. This diagram may be helpful as long as you don't take it too literally.

className{
  //instance variable declarations
  //class variable declarations
  //instance methods{
      //local variables
      //control code
    }//end instance method
  //class methods{
      //local variables
      //control code
    }//end class method
}//end class definition

The Class Declaration

The minimum information in a class declaration must include

Class names must be any legal Java identifiers. By convention, many Java programmers begin the name of the class using an upper-case letter.

In Java, the name of the class becomes the name of a new type.

In addition to naming the class, the declaration can also provide the following information:

Declaring the Superclass of a Class

By default, every class in Java is derived, either directly or indirectly, from the class named Object.

C++ does not have a class that is the superclass of all other classes, such as Object in Java.

A new class may be derived directly from Object, or may be derived from another class that is derived from Object or may be derived from another class further down the inheritance hierarchy.

The immediate parent class of a new class is known as its superclass. (Sometimes we use the word superclass to indicate the collection of classes in the inheritance hierarchy from which a specific class is derived.)

If you do not specify the superclass for a new class, it will derive directly from Object. (The Object class is defined in the package named java.lang.)

The keyword extends is used in the class declaration to specify the immediate superclass of the new class using the syntax shown below.

class MyNewClassName extends SuperClassName{
  //body of class
}

.

C++ programmers should note that inheritance in Java does not involve a specification of an access specifier, public, private, or protected at the inheritance interface. In other words, inheritance access control cannot be used in Java to modify the access control assigned to a member of the parent class.

Although it is allowable to extend Object as shown below, this isn't necessary because Object is the default parent class when no other parent class is specified.

class MyNewClassName extends Object{
  //body of class
}

.

A class inherits the variables and methods of its superclass, and of the superclass of that class, etc., all the way back up the family tree to the single class which is the root of all inheritance: Object.

Thus, an object that is instantiated from a class contains all the variables and methods defined for that that class and all its ancestors.

However, the methods may have been modified (overridden) somewhere along the way. Also, access to those variables and methods may have been restricted through use of the public, private, and protected keywords.

We will be discussing much of this in increasing detail as we continue through this lesson.

Identifying Interfaces Implemented by a Class

Public, Abstract, and Final Classes
A Brief Word About Packages
Public Classes
Abstract Classes
Final Classes
Class Declaration Summary

 

According to Campione and Walrath, http://java.sun.com/books/Series/Tutorial/java/javaOO/interfaces.html, The Java Tutorial:

An interface declares a set of methods and constants without specifying the implementation for any of the methods.

A class may implement one or more interfaces using the keyword implements and a comma-delimited list of interface names as shown below.

class MyClassName extends MySuperClass 
                  implements MyInterface, UrInterface {
  //body of class
}

Whenever a class claims to implement an interface, you can be assured that it provides a definition for all the methods declared within that interface. Otherwise, the class cannot be compiled.

There is a similarity between an interface and an abstract class, which will be discussed later. However, while an abstract class may contain some method definitions, method definitions are not allowed in an interface. Therefore, the purpose of the interface matches the name. Its sole purpose is to declare the interface, but not to define how that interface is implemented.

We will have a lot more to say about the interface in a subsequent lesson, particularly with respect to how and why you would use it. For the time being, let it suffice to say that if your class implements an interface, you must provide a complete definition for all methods declared in the interface.

When implementing an interface, the method signatures of the methods defined in the class must match the signatures of the methods declared in the interface.

Public, Abstract, and Final Classes

Classes can be declared to be either public, abstract, or final, or some combination of the three. This is accomplished using the appropriate modifiers ahead of the keyword class in the class declaration. However, before we can make any sense out of this, we need to know a little about how classes are grouped into packages.

A Brief Word About Packages

Later we will learn how to group classes into packages. For the time being, consider a package to be a group of probably related classes in the same subdirectory.

In the simplest case, the classes must be in a directory having the same name as the package. As a practical matter, for those familiar with pathnames, you can consider the package to be the same as the fully-qualified pathname to the directory containing a specific class file.

For example, again, quoting Campione and Walrath,

"the .class files for java.util are in a directory named util in a directory named java somewhere in your CLASSPATH."

For the time being, consider CLASSPATH to be a system environmental variable (that can be set at runtime or in your autoexec.bat file) which tells your system where to search for the required class files.

However the simplest case described above doesn't normally exist and this can lead to some confusion. After installing a Java development kit such as Sun's JDK 1.1.5, it is not likely that you will find a directory named java which has a subdirectory named util which contains a large number of files with an extension of class.

The later versions of Java have the capability to search consolidated files using the zip consolidation technology. This results in a considerable savings of disk space. The zip consolidation technology has the ability to remember the directory structure that contained the files before they were consolidated. Therefore it is probably closer to the truth to paraphrase the above quotation something like the following:

Somewhere on your disk, you will find a zip file containing a large number of class files. Prior to consolidation, the .class files for java.util were in a directory named util, which was in a directory named java. Wherever this zip file is stored, it must be somewhere in your CLASSPATH.

Public Classes

Before getting into access control for classes, note that there is no special relationship between the inheritance hierarchy and the location of class files in packages. A class file may be in the same package as the class file for its superclass, or it may be in a different package. Similarly, it may or may not be in the same package as the class files for its siblings.

By default, a class can be used only by the objects of other classes in the same package.

You can make the class available to objects of classes outside that package by declaring it to be public using the following syntax.

public class MyClass extends MySuperClass 
                     implements MyIntfc, UrIntfc {
  //body of class
}

Abstract Classes

An abstract class is a class that is designed to be inherited from (subclassed). It is not intended to be a class from which objects are instantiated.

An abstract class may contain abstract methods, but this is not a requirement.

An abstract method is a method for which only the method signature (known as a function prototype in C++) is provided. We will discuss the reasons for creating abstract classes later.

Final Classes

The opposite of an abstract class is a final class. A final class cannot be subclassed. The reasons for using final classes will also be discussed later.

While it is technically possible to declare a class with several combinations of public, abstract, and final, it doesn't make any sense to cause a class to be both abstract and final, and an attempt to do so will result in a compiler error.

Class Declaration Summary

Taking all factors into account, the syntax for a class definition is as follows:

Modifiers class ClassName extends SuperClassName 
                          implements InterfaceNames {
  ...
}

where the items in Italics are optional and the items in boldface are required.

Other than the opening and closing braces, only the class keyword and the name for the class are required.

If you don't specify otherwise, Java assumes a non-final, non-public, non-abstract, subclass of the class Object that doesn't implement any interfaces.

.

The Body of the Class

Member Variables
Constants
Methods

As mentioned earlier, the definition of a class consists of two parts:

The previous section described the class declaration. This section describes the class body.

The body is made up of two types of members:

Each of these comes in two varieties,

(as in class variables and instance variables).

An object instantiated from a class is said to have

The current values of the variables define the current state of an object, while the methods define its behavior.

Typically in object-oriented programming, we restrict direct access to the variables and provide access to those variables only through accessor methods, but this is not required.

Some or all of the variables may be declared in such a way (using the keyword final) that they behave like constants .

Objects instantiated from the class contain all the members of the class, and may also contain other members that are inherited from the superclass and its ancestors.

For example, all objects in Java inherit directly or indirectly from the Object class. Thus, every object contains the members of the Object class.

Therefore, the Object class defines the basic state and behavior of every object in Java.

Note that this differs significantly from C++ where there is no central class from which all other classes inherit. Thus, there is no basic definition of the state and behavior of a class in C++.

The Object class imparts several important behaviors to its descendants including:

These capabilities will be discussed in more detail later when we discuss the Java standard library classes.

Member Variables

The minimum declaration for member variables in both Java and C++ includes the type and the name using the following syntax.

type variableName;

This syntax is the same as used when declaring variables in other parts of the program, such as

A member variable declaration appears within the class body, but outside the definition of any method.

A variable declared within the definition of a method becomes a local variable to that method and is not a member variable of the class.

The type of a member variable determines the values that can be assigned to it as well as the operations that can be performed on it.

The name of a member variable can be any legal Java identifier.

Typically Java programmers begin the variable name with a lower-case letter, but this is not required.

The names of all member variables must be unique within the class.

In Java, a member variable and a method can have the same name.

Java allows you to initialize member variables when you declare them.

In C++, member variables may not have the same name as methods. If they are the same, a compiler error will result.

Beyond simply declaring the type and the name of a member variable, there are some differences between Java and C++, in syntax and interpretation. Some of those differences follow:

  • Both languages allow you to declare static member variables using the same syntax with generally the same interpretation (but in C++, you must re-declare static member variables outside the class definition)..
  • Both languages allow you to provide an access specifier for the member variable using the keywords public, private, and protected, but the syntax and the interpretation is different between the two languages.
  • Both languages (are intended to) recognize the keyword volatile using generally the same syntax with generally the same interpretation. However, Sun's JDK 1.0 ignores volatile.
  • C++ does not recognize the keywords transient and final used with member variable declarations in Java.

In addition to the differing use of syntax and attributes described above, Java allows you to initialize member variables of primitive types with you declare them. This is not allowed in C++.

The complete syntax of a member variable declaration in Java is as follows where the italicized items are optional and the boldface items are required.

accessSpecifier static final transient volatile type variableName 
       = initialValueForPrimitiveTypes or new type(optionalParameters);

A brief interpretation of the modifiers is described below. More detailed discussions follow in this or other lessons.

Another important difference between Java and C++ has to do with the declaration of static member variables. In C++, if you declare a member variable to be static within a class, you must re-declare it again outside the class using the name of the class, the name of the variable, and the scope resolution operator. If it is of a primitive type, you can also initialize it when you re-declare it, but that is not required.

Java does not require re-declaration of static member variables outside the class, and if they are of primitive type, they can be initialized inside the class when they are declared.

Constants

The final keyword is used in Java to cause a variable to behave like a constant, meaning that it cannot be modified after it is declared and initialized.

The final keyword is not supported by C++.

Because a final variable is a constant, it must be given a value (initialized) when it is declared. A typical declaration of a final variable follows:

class Circle{
  final float PI = 3.14159;
  ...
}

If you write code that attempts to modify a final variable, you will get a compiler error.

Later we will learn that the final keyword can also be applied to methods, meaning that they cannot be overridden. Similarly, the final keyword can be applied to class definitions meaning that they cannot be subclassed.

Methods

The Method Declaration
Returning a Value from a Method
The Name of the Method
Other Elements of a Method Declaration
Passing Information to a Method
The this Keyword
The super Keyword
Local Variables

 

The implementation of a method can also be thought of as consisting of two parts:

This can be seen schematically in the following.

returnType functionName( formal argument list){
  //body
}

In both Java and C++, the minimum declaration consists of

In Java, the full definition of the method, including the body, must be placed inside the class definition.

.

In C++, the method can be declared inside the class definition with the full definition including the body being placed outside the class. Alternately, under certain circumstances, in C++, the full definition can be placed inside the class definition, which makes it an automatic inline function.

Placing the full definition of the method inside the class definition in Java does not cause it to be an inline method. Java doesn't support the concept of inline methods.

Java does not make provisions for the programmer to distinguish between inline and ordinary methods. (Sometimes the compiler may choose to make a method inline for efficiency purposes.)

In both Java and C++, methods may have numerous other attributes including access control, static or non-static, etc.

The syntax used to cause a method to be static as well as the interpretation of static methods is generally the same between Java and C++ (although the syntax used to access a static method differs between the two).

The syntax used to establish access control and the interpretation of access control differs significantly between Java and C++.

In both Java and C++, parameters are optional, and in both cases, the formal argument list (method signature) consists simply of a set of empty parentheses if there are no parameters.

Optionally C++ allows the keyword void to be used in an empty argument list. Pascal omits the parentheses entirely when there are no parameters for a function or procedure.

The parameters are used in both Java and C++ to pass information to the body of the method, and can also be used to pass information from the body of the method back to the calling method in certain situations.

Stated differently, method parameters are used to provide information to a method from outside the scope of the method or to pass information from the scope of the method to the outside world.

The Method Declaration

The method declaration in both Java and C++ provides the following information:

The minimum required information is the

In some cases, the number of arguments is zero, in which case the argument list is simply left blank.

Java and C++ use the same syntax and same interpretation for the name, return type, and arguments.

The syntax and interpretation of access control is significantly different between Java and C++.

The following code fragment shows a minimal method declared within a class.

class MyClass{
  ...
  int myMethod(){      
    ...
  }//end myMethod
}//end class

This code declares a method named myMethod, which returns a value of type int and requires no arguments.

Returning a Value from a Method

Both Java and C++ require that the method declaration indicate the type of the return value.

If there is no return value, the type of the return value must be specified as void.

In both Java and C++, the return keyword is used to return a value (or an object) using the syntax shown below.

The return keyword is followed by an expression which evaluates to the value (or object) to be returned. The expression can be very complex, or can be as simple as the name of an object, a primitive variable, or a constant.

return expression;

.

Methods and functions in C++ can return a variable or object either by value (a copy is returned), by pointer, or by reference.

Java does not support pointers, so it cannot return a pointer.

All primitive types in Java are returned by value which means that a copy of the result of evaluating the expression is returned.

All object types in Java are often said to be returned by reference.

What this really means is that a copy of a reference variable is returned meaning that the reference variable is actually returned by value.

However, since the copy of the reference variable can be used to access the object, it doesn't matter that it is only a copy. Furthermore, the existence of the copy of the reference variable is sufficient to prevent the object from becoming eligible for garbage collection when the method terminates.

As a practical matter, returning a reference to an object in Java is similar to returning a pointer to a dynamically allocated object in C++, except that the syntax for dealing with the returned item is much simpler in Java. In either case, the item that is returned is the (direct or indirect) address of a location in dynamic memory where the object is stored.

The following Java application illustrates returning by value and by reference. The output from the program is shown in the comments at the beginning of the program.

/*File return3.java Copyright 1997, R.G.Baldwin
Illustrates returning by value and by reference in Java.

The output from the program is:

Value returned is 5
Value of instance variable in returned object is 10
********************************************************/

//An object of this class will be returned by reference
class NewClass{ 
  int instanceVariable = 10;
}//end NewClass
//=====================================================//

class return3 { //define the controlling class

  int returnValue() {//function which returns by value
    return 5; //return a primitive type by value
  }//end returnValue()
  //---------------------------------------------------//

  //function which returns by reference  

  NewClass returnReference() {
    return new NewClass();//return an object by reference
  }//end returnReference()
  //---------------------------------------------------//

  public static void main(String[] args){ //main method
    return3 obj = new return3();//instantiate object
    System.out.println(
              "Value returned is " + obj.returnValue() );
    System.out.println(
      "Value of instance variable in returned object is "
              + obj.returnReference().instanceVariable );
  }//end main
}//End return3 class.

.

The following C++ program is similar to the above Java application. In this case, the program illustrates returning by value, pointer, and reference. If you examine the structure of this program carefully and compare it with the above Java application, you will note that returning by pointer in C++ is very similar to returning by reference in Java, because all reference objects in Java are instantiated in dynamic memory (on the heap).

In C++, you must make certain that anything that you return by reference is guaranteed to persist after the function terminates. For that reason, the value that was returned by reference was made a static variable in the following C++ program.

The output from running this program is shown in the comments near the beginning of the program.

/*File return3.cpp Copyright 1997, R.G.Baldwin
Illustrates returning by value, reference, and pointer
in C++.

The output from this program was:

Value returned by value was 5
Value returned by reference was 15
Value contained in object returned by pointer was 10

******************************************************/

#include<iostream.h
//an object of this type will be returned by pointer
class NewClass{
public:
  int instanceVariable;
  NewClass(){instanceVariable = 10;}//constructor
};//end NewClass

  //function to return by value
  int returnValue() {return 5;}

  //function to return by reference
  int returnReference(){
    static int localVar = 15;
    return localVar;
  }//end returnReference()

  //function to return by pointer
  NewClass* returnPointer() {
    return new NewClass;
  }//end returnPointer()

class return3 {
public:
  static void classMain(){
  cout << "Value returned by value was "
                                << returnValue() << endl;
  cout << "Value returned by reference was "
                            << returnReference() << endl;
  cout << "Value contained in object returned by pointer"
    " was " << returnPointer()-instanceVariable << endl;
  }//end classMain
};//End return3 class definition.
//=====================================================//

void main()
{
  //call the class method named classMain
  return3::classMain();
}//end main

//End C++ program

Neither Java nor C++ require that the calling program recognize the return value. On the other hand, all but the very latest Pascal compilers require that the program recognize returned values from functions.

All but the very latest Pascal compilers require that the program recognize returned values from functions.

If a Java program returns a reference to an object and that reference is not assigned to a reference variable (or used in a larger overall expression), the object is immediately eligible for garbage collection (assuming that the reference is not already stored in some other reference variable).

This is illustrated by the following Java application, which makes a call to a method that returns a reference, but ignores the returned reference. The program then requests garbage collection and goes to sleep for one second. The object that was ignored is finalized and garbage collected while the main thread is sleeping and before the program actually terminates.

/*File return4.java Copyright 1997, R.G.Baldwin
Illustrates ignoring a return value in Java.

The ignored object is finalized and garbage collected
before the program terminates.

The output from the program is:

This program ignores returned object
Requesting garbage collection
Going to sleep for one second
Finalizing object 10
Terminating program
********************************************************/

//An object of this class will be returned by reference
class NewClass{ 
  int instanceVariable = 10;
  //---------------------------------------------------//
    
  //Override the finalize method for this class
  protected void finalize(){
    System.out.println("Finalizing object " 
                                    + instanceVariable);
  }//end overridden finalize method  
}//end NewClass
//=====================================================//

class return4 { //define the controlling class
  //function which returns by reference
  NewClass returnReference() {
    return new NewClass();//return object by reference
  }//end returnReference()
//-----------------------------------------------------//

  public static void main(String[] args){//main method
    //Set up to run finalizer on exit
    System.runFinalizersOnExit(true);
    
    return4 obj = new return4();//instantiate object
    
    //Call method and ignore return value
    obj.returnReference(); 
    System.out.println(
              "This program ignores returned object");
    System.out.println("Requesting garbage collection");
    System.gc();//request garbage collection 
    System.out.println("Going to sleep for one second");
    try{
      Thread.currentThread().sleep(1000);
    }catch(InterruptedException e){}
    System.out.println("Terminating program");
  }//end main
}//End return4 class.

.

If a C++ program returns a pointer to an object in dynamic memory and the value of that pointer is not assigned to a pointer variable, the opportunity to return that memory to the operating system is lost forever, and a memory leak will have occurred (assuming that the address is not already stored in some other pointer variable).

.

In Java, the type of the returned value or object must match the return type specified in the method declaration, or must match a subclass of the specified type.

Matching a subclass of the specified type is possible because all classes in Java inherit from the common root Object, and generally it is acceptable to store a reference to an object in a reference variable which is a superclass of that object.

Later we will discuss the topics of upcasting and downcasting to deal with situations of this sort.

Later we will also discuss using the interface as a type. If the return type is an interface type, the returned object in Java must implement the specified interface.

In C++, the type of the returned value must match the return type specified in the method declaration,

.

The Name of the Method

The name of the method can be any legal Java or C++ identifier, depending on the language being used.

Method Overloading: Both Java and C++ support a concept known as method overloading.

Method overloading allows two or more methods to share the same name, provided that the formal argument lists of the two are different in a way which is discernible to the compiler.

In other words, the compiler must be able to examine a call to the method and determine, on the basis of the parameters being passed to the method, which version of the method to use in that instance.

In C++, some argument lists may appear at first glance to be different, but are not discernibly different to the compiler due to factors such as default arguments and automatic type conversions. This results in ambiguity errors at compile time.

The compiler determines at compile time which version of the overloaded function to call by matching the number and/or order of types in the argument list and the parameters used in the method call. (The names of the parameters are of no consequence in this regard.)

You cannot declare two methods with the same name and the same formal argument list. The following code fragment shows a Java class with four overloaded methods, one of which is not legal because it has the same name and the same argument list as the previous method.

class MyClass{
  ...
  void myFunction(int x, int y) { ... }
  void myFunction(int x) { ... }
  void myFunction(int x, float y) { ... }
//void myFunction(int a, float b) { ... } //not allowed
}//end MyClass

An object-oriented language is expected to support encapsulation, inheritance, and polymorphism.

Function overloading provides a feature that some authors refer to as compile-time polymorphism. Other authors, however, do not consider this to be polymorphism.

In both Java and C++, two or more overloaded versions of the same method can return different types. The return type is of no particular consequence in method overloading.

Constructors: In both Java and C++, any method whose name is the same as the name of the class is a constructor.

Constructors do not specify a return type, and a constructor cannot contain a return statement.

Constructors can be overloaded.

Although you can put any legal code into a constructor, the primary purpose of a constructor is to initialize a new object.

In C++, the constructor is automatically called whenever you instantiate a new object using any legal method of instantiation. It is also allowable in C++ to make direct calls to the constructor.

In Java, when instantiating an object, you always make a direct call to the constructor as an argument to the new operator as in the following code fragment.

MyClass obj = new MyClass(7, 3.14);

This statement accomplishes declaration, instantiation, and initialization all in one statement. The code on the left of the assignment operator accomplishes declaration (notifying the compiler of the name of the object).

The new operator accomplishes instantiation by causing memory to be set aside to contain the object.

The call to the constructor as the right operand of the new operator initializes the object, presumably using the two parameters that are passed to the constructor.

In both Java and C++, if you don't provide a constructor, the system will provide a default constructor for you (the default constructor takes no parameters and is often referred to as the NoArg constructor).

In Java, the default constructor will automatically initialize the member variables to zero or the equivalent of zero.

The default constructor in C++ does not perform any initialization.

.

You can think of the default constructor in Java as a method having the same name as the class with an empty argument list that you (sometimes) don't have to write.

.

Think of the default constructor in C++ as the constructor which gets called when you instantiate an object without any parameters as in:

MyClass obj;

.

In both languages, if you provide one or more constructors, the default constructor is not provided for you automatically. If you need a constructor with no arguments in that case, you must provide it yourself.

Overriding Methods: In both Java and C++, an instance of a class (an object) contains all the instance variables and instance methods of the class and all its superclasses.

Both languages also support the notion that a class may override a method in a superclass having the same signature. The purpose of overriding a method is to change its behavior relative to objects of a subclass.

The procedures for overriding methods are completely different between Java and C++. They are so different, that the method of overriding methods in C++ will not be discussed further here.

You must not confuse overloading and overriding methods. As a matter of terminology, note that:

Overriding methods in Java requires that they have the same signature including the argument list and all the other elements that go to make up the signature.

In Java, if a class defines a method with the same signature as a method in a superclass, the new method will override the superclass method insofar as objects of that subclass type are concerned. Whenever that method is invoked on an object of the subclass, the overridden version will be invoked. This will be discussed in more detail later.

Other Elements of a Method Declaration

The full declaration of a method is shown below with the optional items shown in Italics and the required items shown in boldface.

accessSpecifier static abstract final native synchronized 
    returnType methodName( paramList ) throws exceptionList

Some of these modifiers will be discussed briefly here, and in more detail later. Others will not be discussed until later.

Passing Information to a Method

In Java, all methods must be declared and defined within the class, and you must provide the types of the arguments as well as the names of the arguments.

In C++, you can declare a method in a class and define it either inside the class (under certain restricted conditions) or define it outside the class. When you declare a method in C++, you are required to specify the types of arguments, but you are not required to provide names for the arguments (but you can if you want to). When you define the method, you must provide names for the arguments.

In both languages, the arguments behave as local variables in the body of the method having the specified names. Those variables are initialized by the values passed as parameters into the method. The scope of these variables is the full extent of the method.

In C++, any argument can be passed by value (copy), pointer, or reference. (For those who remember their Pascal, passing by value in C++ is the same as passing by value in Pascal, and passing by reference in C++ is essentially the same as passing a VAR parameter in Pascal.)

Java doesn't support pointers so you cannot pass by pointer in Java.

Many books will state that In Java, all arguments of primitive types are passed by value and all objects are passed by reference.

It is probably more correct to say that in Java we pass primitive variables by value and we pass references to objects, also by value.

What this really means is that Java also passes reference variables by value. Normally the fact that the method receives a copy of the reference variable doesn't matter. It can use that copy to access the object referred to by the reference variable. This makes it possible for the code in the body of the method to modify the object referred to by the copy of the reference variable.

However, it does matter if you want the code in the method to modify the original value of the reference variable (make the original reference variable refer to a different object). That is not possible because the method doesn't have access to the original. It only has access to the copy.

When you pass a reference variable that refers to an object, you are passing a form of address that specifies where the object is stored in memory. However, what you pass may not be the direct address where the object is stored. Rather, it may be the address of another reference to the object. This differs depending on the JVM. One approach is more efficient for some types of operations while the other approach is more efficient for other types of operations.

In Java, C++, and Pascal, modifying a local variable in a method that was created by passing by value will not modify the original variable that was passed to the method.

On the other hand, modifying an object in a method using a local reference variable that was initialized by passing a copy of a reference variable will modify the original object. In Java, this amounts to modifying the object referred to by the reference variable that was passed to the method.

Modifying variables passed by pointer in C++ is more complicated, but pointers can also be used to modify the original variable passed to the method.

The following Java application illustrates passing primitive variables by value and passing references to objects.

/*File pass1.java Copyright 1997, R.G.Baldwin
Illustrates passing primitive variables by value and 
passing references to objects.

The output from running this program is:

In main
Value of primitiveVariable is 200
Value contained in object is 100
In function passVariables
Value of primitiveVariable is 200
Value contained in incoming object is 100
Modifying values of arguments
Still in function passVariables
Value of primitiveVariable is 201
Value contained in object is 101
Back in main
Value of primitiveVariable is still 200
Value contained in obj is now 101
********************************************************/

//class used to instantiate an object
class NewClass{ 
  int instanceVariable = 100;
}//end NewClass

class pass1 { //define the controlling class

  //function used to illustrate argument passing
  void passVariables(int primVar, NewClass refVar){
    System.out.println("In function passVariables");
    System.out.println("Value of primitiveVariable is " 
                                            + primVar);
    System.out.println("Value contained in incoming " +
                 "object is " + refVar.instanceVariable);

    System.out.println("Modifying values of arguments");
    refVar.instanceVariable = 101;
    primVar = 201;      

    System.out.println("Still in function passVariables");
    System.out.println("Value of primitiveVariable is " 
                                              + primVar);
    System.out.println("Value contained in object is " 
                              + refVar.instanceVariable);
        
  }//end function passVariables

  public static void main(String[] args){ //main method
    //instantiate object for dispatching methods
    pass1 anObject = new pass1();
        
    NewClass obj = new NewClass();//instantiate object
    int primitiveVariable = 200;  //primitive variable

    System.out.println("In main");
    System.out.println("Value of primitiveVariable is " 
                                    + primitiveVariable);
    System.out.println("Value contained in object is " 
                                 + obj.instanceVariable);

    //Invoke method and pass parameters
    anObject.passVariables(primitiveVariable,obj);

    System.out.println("Back in main");
    System.out.println("Value of primitiveVariable is " +
                           "still " + primitiveVariable);
    System.out.println("Value contained in obj is now " 
                                 + obj.instanceVariable);
  }//end main
}//End pass1 class.

In Java, if you want a method to modify a primitive variable that is passed to the function, you must encapsulate that primitive variable in an object wrapper and pass a reference to the object. However, you can't use the standard wrapper classes such as Integer for this purpose.

The standard wrapper classes provide immutable (can't be modified) object wrappers around the primitive data types. However, it isn't difficult to define your own wrapper classes to serve this purpose.

In C++, you can pass a pointer (which points to a function) into another function and use that pointer in the second function to call the pointed-to function.

The capability described in the C++ sidebar above is not directly supported by Java. However, in some cases, you might be able to accomplish nearly the same thing by encapsulating the first function as an instance method of an object and then passing the object into another method where the first method can be executed via the object.

This continues to be the topic of numerous discussions (and debates) on the various Java newsgroups.

The this Keyword

Normally, methods in both Java and C++ have direct access to the member variables of the class.

In both languages, an argument name for a method or the name of a local variable in a method can be the same as the name of a member variable in the class. In this case, the local variable of the method is said to hide the member variable.

In C++, whenever an instance method is invoked, a hidden pointer named this is passed to the method. The this pointer always points to the object which was used to call the method.

In Java, whenever an instance method is invoked, a hidden reference named this is passed to the method. The this reference always refers to the object which was used to call the method.

In both languages, this can be used to access the instance variables hidden by the local variables of the same name.

One prominent author refers to this as a way to "disambiguate" the member variable name.

The use of the this pointer is illustrated in the following C++ program. The output from the program is shown in the comments at the beginning of the program.

The following C++ program uses the this pointer to "disambiguate" the member variable name.

/*File hide1.cpp Copyright 1997, R.G.Baldwin
Illustrates use of this pointer to access a hidden
member variable.

The output from this program is:

Local myVar contains 10
Instance variable myVar contains 5
 
******************************************************/

#include<iostream.h

class hide1 {
  int myVar;  //member variable named myVar
public:
  hide1(){myVar = 5;}//constructor
  //function with argument named myVar
  void myFunction(int myVar){
    cout << "Local myVar contains " << myVar << endl;
    cout << "Instance variable myVar contains "
                                 << this-myVar << endl;
  }//end myFunction
  static void classMain(){
    hide1 obj; //declare an object of this type
    obj.myFunction(10);
  }//end classMain
};//End hide1 class definition.
//=====================================================//

void main()
{
  //call the class method named classMain
  hide1::classMain();
}//end main

The following Java application illustrates the use of the this reference to disambiguate a hidden instance variable twice: once in the constructor and once in the method named myFunction. The syntax used in the constructor is very commonly used in Java.

/*File hide1.java Copyright 1997, R.G.Baldwin
Illustrates use of this pointer to access a hidden 
instance variable.

The output from this program is:

Local myVar contains 10
Instance variable myVar contains 5
**********************************************************/

class hide1 {
  int myVar;  //instance variable named myVar

  //Constructor with argument named myVar
  public hide1(int myVar){//constructor
    //Note use of the this reference here.
    this.myVar = myVar;
  }//end constructor
  //-----------------------------------------------------//
  
  //Function with argument named myVar
  void myFunction(int myVar){ 
    System.out.println("Local myVar contains " + myVar);
    
    //Note the use of the this reference here
    System.out.println("Instance variable myVar contains " 
                                             + this.myVar);
  }//end myFunction
  //-----------------------------------------------------//

  public static void main(String[] args){ //main method
    //instantiate object of this type passing in 5
    hide1 obj = new hide1(5);
    //use it to call the method passing in 10
    obj.myFunction(10); 
  }//end main method
}//End hide1 class definition.

The concept of the this reference is so important that we need to emphasize its characteristics.

In both Java and C++, when an object is used to invoke an instance method, an address or a reference to the object is passed to the method. That address or reference is contained in an entity named this.

In Java, this is used as a reference to the object.

In C++, this is used as a pointer to the object.

In Java, the reference contained in this is a reference to the object that was used to invoke the method.

In C++, the this pointer contains the actual address of the object in memory.

In both Java and C++, the code in the body of the method can use this to access instance members of that specific object for a variety of purposes.

The super Keyword

If your method overrides a method in its superclass, you can use the keyword super to bypass the overridden version in the class and invoke the version in the superclass.

super is a concept of Java that does not exist in C++, at least not with a similar implementation.

Likewise, if your method hides a member variable in the superclass, you can use the keyword super to access the member variable in the superclass.

You can also use super in a constructor of your class to invoke the constructor in the superclass.

The following program uses super to disambiguate a local variable in a method and an instance variable in the superclass having the same name.

The program also uses super to call the superclass constructor from the subclass constructor, which is another important use of super.

When super(parameters) is used to invoke the superclass constructor, it must be the first executable statement in the constructor.

Whenever you invoke the constructor of a class to instantiate an object, if your constructor doesn't have a call to super() as the first executable statement in the constructor, the call is made anyway.

In other words, in order to construct an object of a class, it is necessary to first construct that part of the object attributable to the superclass. That normally happens automatically, making use of the superclass constructor that doesn't take any parameters.

If you want to use a version of the superclass constructor that takes parameters, you can make your own call to super(parameters) as the first executable statement in your constructor as is the case in this program.

/*File super1.java Copyright 1997, R.G.Baldwin
Illustrates use of super reference to access constructor in
superclass.  Also illustrates use of super to disambiguate
local variable from instance variable in superclass.

The output from this program is:

In base class constructor. Setting baseData to 100
In subclass constructor. Setting subClassData to 200
In main
Instance var in base class contains 100
Instance var in subclass contains 200
In function myFunc
Value of local baseData var is 300
Value of instance var named basedata is 100
**********************************************************/
class base{
  int baseData;

  public base(int baseData){//base class constructor
    System.out.print("In base class constructor. ");
    System.out.println("Setting baseData to " + baseData);
    this.baseData = baseData;
  }//end base constructor
}//end base class definition
//=======================================================//

class super1 extends base{
  int subClassData;

  public super1(){ //subclass constructor
    super(100); //call superclass constructor with 100
    System.out.print("In subclass constructor. ");
    System.out.println("Setting subClassData to 200");
    subClassData = 200;
  }//end subclass constructor
  //-----------------------------------------------------//

  //Function to illustrate use of super to disambiguate 
  //  local variable and instance variable with same name
  void myFunc(){ 
    //create var to hide base instance var
    int baseData = 300;
    System.out.println("In function myFunc");
    System.out.println("Value of local baseData var is "
                                               + baseData);
    System.out.println("Value of instance var named " +
                          "basedata is " + super.baseData);
  }//end function myFunc
  //-----------------------------------------------------//

  public static void main(String[] args){ //main method
    //instantiate an object of this type 
    super1 obj = new super1();
    System.out.println("In main");
    System.out.println("Instance var in base class " +
                               "contains " + obj.baseData);
    System.out.println("Instance var in subclass contains "
                                       + obj.subClassData);

    //Call method to illustrate use of super to 
    // disambiguate local variable and instance variable 
    // with same name
    obj.myFunc();
  }//end main method
}//End super1 class definition.

As mentioned earlier, if your method overrides a method in its superclass, you can use the keyword super to bypass the overridden version and invoke the version in the superclass.

This is illustrated by the following program. This program contains an overridden version of a superclass method named myMethod() that uses the value of an incoming parameter to decide whether to invoke the superclass version or to execute its own code.

Obviously it would be possible to do both as well. In other words, there is no reason that an overridden method could not invoke the superclass version using the super keyword, and then execute additional code to provide additional behavior.

/*File super2.java Copyright 1997, R.G.Baldwin
Illustrates bypassing a local overridden method in favor
of the method in the superclass.

The output from this program is:

In main
Incoming parameter is false
Overridden method invoked
Incoming parameter is true
Base-class method invoked

**********************************************************/
class base{
  void myMethod(boolean superFlag){//method to override
    System.out.println("Incoming parameter is " 
                                            + superFlag);  
    System.out.println("Base-class method invoked");
  }//end myMethod
}//end base class definition
//=======================================================//

class super2 extends base{
  void myMethod(boolean superFlag){//override myMethod()
    //Make decision to invoke this version or the version
    // in the superclass.
    if(superFlag)super.myMethod(superFlag);//super version
    else{ //this version
      System.out.println("Incoming parameter is " 
                                              + superFlag);
      System.out.println("Overridden method invoked");
    }//end else
  }//end overridden myMethod()
  //-----------------------------------------------------//

  public static void main(String[] args){ //main method
    //instantiate an object of this type 
    super2 obj = new super2();
    System.out.println("In main");
    //Invoke overridden version of myMethod()
    obj.myMethod(false);
    //Invoke superclass version of myMethod()
    obj.myMethod(true);
  }//end main method
}//End super2 class definition.

.

Local Variables

As in most modern programming languages, Java allows you to declare variables and objects in the body of a method (or within a block of statements within the body of a method). Variables declared in this manner are commonly known as automatic local variables.

The visibility of such a variable is limited to the block of statements in which it is declared.

The life of such a variable is limited to the period during which control remains within the block of statements in which it is declared.

C++ allows you to declare variables in a method as static variables. In this case, the variable continues to exist for the entire life of the overall program, and furthermore, values stored in a static variable persist from one method call to the next call to the same method. This concept is not supported by Java.

Both Java and C++ allow you to use the new operator to instantiate objects in dynamic memory within the body of a method.

In Java, the actual life of the object (period during which it occupies memory) extends until it is garbage collected but the useful life of the object extends until it becomes eligible for garbage collection. (Once it becomes eligible for garbage collection, it can no longer be accessed, and therefore cannot serve any useful purpose.)

The object becomes eligible for garbage collection as soon as its reference is no longer contained in a reference variable.

In C++, that object continues to occupy memory until the delete operator is used to return the memory occupied by the object to the operating system.

Review

Q - Object-oriented programming requires encapsulation, inheritance, and polymorphism. The class is the central concept of Java primarily intended to support which of the three?

A - The class is the central concept of Java that supports encapsulation.

Q - The class provides the plan from which objects are built. This plan defines the data that is to be stored in an object, and the methods for manipulating that data: True or False? If false, explain why.

A - True.

Q - According to Baldwin's Java tutorial, the definition of a class consists of two parts. What are they. Provide a pseudocode fragment to illustrate your answer.

A - The definition of a class deals with two parts: declaration and body using the general syntax shown below.

classDeclaration{
  classBody
}

Q - The declaration of a class notifies the compiler of the name of the class, and can provide other information as well. What are three other types of information that the declaration can provide to the compiler?

A - The declaration notifies the compiler of the name of the class, and also can provide other information such as

Q - According to Baldwin's Java tutorial, what is contained in the classBody of a class definition?

A - The classBody contains the declarations for, and possibly the initialization of, all data members (both class variables and instance variables) as well as the full definition of all methods.

Q - There are at least two different places where variables can be declared. What are those places?

A - Variables may be declared either

Q - Variables which are declared inside the body of a method are member variables of the class: True or False? If false, explain why.

A - False. Variables that are declared inside the body of a method are not member variables of the class. Rather, they are local variables in the method.

Q - In addition to the use of open and close braces, what is the minimum information that a class declaration must provide?

A - The minimum information in a class declaration must provide is:

Q - By default, every class in Java is derived, either directly or indirectly, from the class named ___________. Provide the name of the class.

A - By default, every class in Java is derived, either directly or indirectly, from the class named Object.

Q - The immediate parent class of a new class is known as its superclass: True or False? If false explain why and provide a code fragment to illustrate your answer.

A - True. The immediate parent class of a new class is known as its superclass.

Q - If you do not specify the superclass for a new class, it will derive directly from _______. Provide the name of the class and the package in which it is defined.

A - If you do not specify the superclass for a new class, it will derive directly from Object. (The Object class is defined in the package named java.lang.)

Q - What is the keyword that is used in the class declaration to specify the superclass of the new class. Provide a code fragment illustrating your answer and the proper usage syntax of the keyword.

A - The keyword extends is used in the class declaration to specify the superclass of the new class using the syntax shown below.

class MyNewClassName extends SuperClassName{
  //body of class
}

Q - Is it allowable to extend Object as shown below. If not, why not. If it is allowable, is it necessary?

class MyNewClassName extends Object{
  //body of class
}

A - Although it is allowable to extend Object as shown, this isn't necessary because Object is the default parent class when no other parent class is specified.

Q - Provide the definition of an interface from Baldwin's Java tutorial, and identify the specific lesson that contains that definition.

A - Lesson Java038.htm. According to Campione and Walrath,

"An interface declares a set of methods and constants without specifying the implementation for any of the methods."

Q - Because Java doesn't support multiple-inheritance, a class may implement only one interface: True or False? If false, explain why and show a code fragment that illustrates your answer.

A - False. A class may implement one or more interfaces using the keyword implements and a comma-delimited list of interface names as shown below.

class MyClassName extends MySuperClass 
                implements MyInterface, UrInterface {
  //body of class
}

Q - Whenever a class claims to implement an interface, can you be assured that it provides a definition for all the methods declared within that interface. Yes or No? If yes, how can you be assured? If no, why not?

A - Whenever a class claims to implement an interface, you can be assured that it provides a definition for all the methods declared within that interface. Otherwise, it cannot be compiled.

Q - There is a similarity between an interface and an abstract class, but there is an essential difference. What is that difference?

A - An abstract class may contain some method definitions. However, method definitions are not allowed in an interface.

Q - According to Baldwin's Java tutorial, the sole purpose of an interface is to declare the interface, but not to define how that interface is implemented: True or False? If false, explain why.

A - True. The purpose of the interface matches the name. Its sole purpose is to declare the interface, but not to define how that interface is implemented.

Q - When implementing an interface, the method signatures of the methods in the class must match the signatures of the methods declared in the interface with the one exception that the return type is not required to match: True or False. If false, explain why.

A - False. When implementing an interface, the method signatures of the methods in the class must match the signatures of the methods declared in the interface in all respects.

Q - Classes can be declared to be either p_______, a_______, or f________, or some combination of the three, by using the appropriate modifiers ahead of the keyword class in the class declaration. Provide the missing modifiers.

A - Classes can be declared to be either public, abstract, or final, or some combination of the three.

Q - We can consider a package to be a group of related classes. In the simplest case, the classes must either be in a directory having the same name as the package, or in a subdirectory of that directory, or a subdirectory of that subdirectory, etc. True or False. If false, explain why.

A - True.

Q - You can consider PATH to be a system environmental variable (that can be set at runtime or in your autoexec.bat file) which tells your system where to search for the required class files: True or False? If false, explain why.

A - False. CLASSPATH, (not PATH), is the system environmental variable (that can be set at runtime or in your autoexec.bat file) which tells your system where to search for the required class files.

Q - After installing a Java development application such as Sun's JDK 1.1, it is likely that you will find a directory named java which has a subdirectory named util which contains a large number of files with an extension of class: True or False? If false, explain why and also explain what you are likely to find.

A - False. After installing a Java development application such as Sun's JDK 1.1, it is not likely that you will find a directory named java which has a subdirectory named util which contains a large number of files with an extension of class as a result of the following improvements to the storage of class files in Java..

The later versions of Java have the capability to search consolidated files using the zip consolidation technology. This results in a considerable savings of disk space. The zip consolidation technology has the ability to remember the directory structure that contained the files before they were consolidated. Therefore it is probably closer to the truth to paraphrase the above something like the following:

Somewhere on your disk, you will find a zip file containing a large number of class files. Prior to consolidation, the .class files for java.util were in a directory named util that was in a directory named java. Wherever this zip file is stored, it must be somewhere in your CLASSPATH.

Q - By default, a class can be used by the objects of all other classes in the program: True or False? If false, explain why and provide a code fragment showing how to make it possible for a class to be used by the objects of all other classes in the program..

A - False. By default, a class can be used only by the objects of other classes in the same package. You can make the class available to objects of classes outside the current package by declaring it to be public using the following syntax.

public class MyClass extends MySuperClass 
                     implements MyIntfc, UrIntfc {
  //body of class
}

C - An abstract class is a class that is designed to be inherited from (subclassed). It is not intended to be a class from which objects are instantiated: True or False? If false, explain why and provide a code a fragment to illustrate your answer.

A - True. An abstract class is a class that is designed to be inherited from (subclassed).

Q - An abstract class must contain abstract methods: True or False? If false, explain why and also provide a description of an abstract method.

A - False. An abstract class may contain abstract methods, but this is not a requirement. An abstract method is a method for which only the method signature is provided.

Q - A final class cannot be subclassed: True or False? If false, explain why and provide a code fragment to illustrate our answer.

A - True. A final class cannot be subclassed (inherited from).

Q - You can declare a class using various combinations of public, abstract, and final. One allowable combination to declare a class that is abstract and public: True or False. If false, explain what will happen if you attempt to do this.

A - True. It is allowable to declare a class to be abstract and public.

Q - You can declare a class using various combinations of public, abstract, and final. One allowable combination to declare a class that is abstract and final: True or False. If false, explain what will happen if you attempt to do this.

A - False. While it is technically possible to declare a class with several combinations of public, abstract, and final, it doesn't make any sense to cause a class to be both abstract and final, and an attempt to do so will result in a compiler error.

Q - Taking all factors into account, show the complete syntax for a class declaration as provided in Baldwin's Java tutorial.

A - Taking all factors into account, the syntax for a class declaration is as follows:

Modifiers class ClassName extends SuperClassName 
                          implements InterfaceNames {
  ...
}

where the items in italics are optional and the items in boldface are required.

Q - When declaring a class, if you don't specify otherwise, Java assumes a non-final, non-public, non-abstract, subclass of the class Object that doesn't implement any interfaces: True or False? If false, explain why and provide a code fragment that illustrates your answer.

A - True.

Q - According to Baldwin's Java tutorial, the body of a class is made up of two types of members and each type comes in two different varieties. What are the two types of members, and what are the two varieties?

A - The body of a class is made up of two types of members:

Each of these comes in two varieties,

as in class variables and instance variables.

Q - Some or all of the variables in a class may be declared in such a way that they behave like constants using the keyword _________. Provide the keyword.

A - Some or all of the variables may be declared in such a way that they behave like constants using the keyword final.

Q - In the absence of overridden methods, there is a class that defines the basic state and behavior of all objects. What is the name of that class?

A - All objects in Java inherit directly or indirectly from the Object class. Thus, every object contains the members of the Object class. Therefore, the Object class defines the basic state and behavior of every object in Java.

Q - The Object class imparts several important behaviors to all objects in Java. List and describe four of those behaviors.

A - The Object class imparts several important behaviors to its descendants including:

Q - Where does the declaration of a member variable appear within the class body?

A - A member variable declaration appears within the class body, but outside the definition of any method.

Q - A member variable declaration can appear anywhere within the class body including within the definition of a method: True or False? If false, explain why.

A - False. A member variable declaration appears within the class body, but outside the definition of any method. If declared within the definition of a method, it becomes a local variable to that method and is not a member variable of the class.

Q - What is determined by the type of a member variable?

A - The type of a member variable determines the values that can be assigned to it as well as the operations that can be performed on it.

Q - The names of all member variables must be unique within the class: True or False? If false, explain why and provide a code fragment that illustrates your answer.

A - True. The names of all member variables must be unique within the class.

Q - In Java, a member variable and a method can have the same name: True or False. If false, explain why and provide a code fragment that illustrates your answer.

A - True. In Java, a member variable and a method can have the same name.

Q - Java allows you to initialize member variables of primitive types with you declare them: True or False. If false, explain why and provide a code fragment that illustrates your answer.

A - True. Java allows you to initialize member variables of primitive types with you declare them.

Q - Show the complete syntax of a member variable declaration as provided in Baldwin's Java tutorial.

A - The complete syntax of a member variable declaration in Java is as follows where the italicized items are optional and the boldface items are required.

accessSpecifier static final transient volatile type variableName 
     = initialValueForPrimitiveTypes or new type(optional parameters);

A brief interpretation of the modifiers is described below.

Q - The final keyword is used in Java to cause a variable to behave like a constant. A final variable can be initialized at any time after it is declared: True or False. If false, explain why and provide a code fragment to illustrate your answer.

A - False. Because it is a constant, a final variable must be given a value when it is declared. A typical declaration of a final variable follows:

class Circle{
  final float PI = 3.14159;
  ...
}

Q - What is the significance of applying the final keyword to a method?

A - The final keyword can be applied to methods, meaning that they cannot be overridden.

Q - What, according to Baldwin's Java tutorial, are the three required elements of the minimum declaration of a method?

A - The minimum declaration consists of

Q - In Java, the full definition of the method, including the body, may be placed either inside or outside the class definition. Placing it inside causes it to be an inline method: True or False? If false, explain why.

A - False. In Java, the full definition of the method, including the body, must be placed inside the class definition, and this does not cause it to be an inline method. Java does not make provisions for the programmer to distinguish between inline and ordinary methods.

Q - In Java, parameters are optional, and the formal argument list (method signature) consists simply of a set of empty parentheses if there are no parameters: True or False? If false, explain why and provide a code fragment to illustrate your answer.

A - True.

Q - Baldwin's Java tutorial provides a four-part list showing the information contained in a method declaration. What are the items on that list.

A - The items on the list of information contained in a method declaration are:

Q - What is the minimum required information in a Java method declaration? Provide a code fragment that illustrates a minimal method declaration within a class declaration where the method returns a value of type int and requires no arguments..

A - The minimum required information for a Java method declaration is:

The following code fragment shows a minimal method declared within a class.

class MyClass{
  //...
  int myMethod(){
    //...
  }//end myMethod
}//end class

This code declares a method named myMethod that returns a value of type int and requires no arguments.

Q - How do you specify the return type of a method for a method that does not return a value?

A - If there is no return value, the type of the return value is specified as void.

Q - In Java, all primitive types in Java are returned by _______. Provide the missing word and explain what this means.

A - All primitive types in Java are returned by value which means that a copy of the variable is returned.

Q - All object types in Java are returned by __________. Provide the missing word.

A - All object types in Java are returned by reference.

Q - In Java, the type of the returned value must match the return type specified in the method declaration, except for a special case where this is not required. Describe that special case and explain why it is possible.

A - In Java, the type of the returned value must match the return type specified in the method declaration, except that the actual return type may be a subclass of the specified return type. This is possible because all classes in Java inherit from the common root Object.

Q - Because of the strong type checking in Java, it is not acceptable to store a reference to an object in a reference variable that is a superclass of that object: True or False. If false, explain your answer.

A - False. Generally it is acceptable to store a reference to an object in a reference variable which is a superclass of that object. This gets involved in the topics of upcasting and downcasting.

Q - Describe the difference between method overloading and method overriding in Java.

A - Method overloading allows two or more methods to share the same name, provided that the formal argument lists of the two are different in a way which is discernible to the compiler.

Method overriding allows the behavior of a method defined in a class to be modified relative to objects of a subclass of that class. Method overriding requires the name, return type, and argument list (as well as any modifiers such as public) of the new method to match the method signature of the overridden method.

Q - The compiler determines at compile time which version of the overloaded method to call based on what?

A - The compiler determines at compile time which version of the overloaded method to call based on the number and/or order of types in the method signature and the parameters used in the method call. (The names of the parameters are of no consequence in this regard.)

Q - What do we call the method whose name is the same of the name of the class of which it is a member?

A - Any method whose name is the same as the name of the class of which it is a member is a constructor.

Q - What is the proper return type for a constructor?

A - Constructors do not specify a return type, and a constructor cannot contain a return statement.

Q - Constructors can be overloaded: True or False? If false, explain why.

A - True. Constructors can be overloaded.

Q - In Java, the constructor is automatically called whenever you instantiate a new object using code such as the following: True or False? If false, explain why and provide a code fragment that illustrates your answer.

A - False. In Java, you must make an explicit call to the constructor to instantiate a new object. Sample code is shown below.

Q - Any time that you define a new class in Java, you must provide a constructor: True or False?

A - False. In Java, if you don't provide a constructor, the system will provide a default constructor for you.

Q - Method arguments behave as global variables: True or False? If false, explain why.

A - False. Method arguments behave as local variables in the body of the method having the specified names. Those variables are initialized by the values passed as parameters into the method.

Q - In Java, all arguments of primitive types must be passed by reference while all objects must be passed by value: True or False? If false, explain why.

A - False. Just the reverse is true. In Java, all arguments of primitive types must be passed by value while all objects must be passed by reference.

Q - In Java, modifying a local primitive variable in a method which was created by passing the variable to the method will modify the original variable which was passed to the method: True or False? If false, explain why.

A - False. In Java, all primitive variables are passed by value. Modifying a local variable in a method that was created by passing by value will not modify the original variable that was passed to the method.

Q - In Java, when an object is used to invoke an instance method, an address is passed to the method contained in an entity named this. The address contained in this is the address of the object that invoked the method. The code in the body of the method can use this to access instance members of that specific object for a variety of purposes: True or False. If false, explain why.

A - True.

Q - If your method overloads a method in its superclass, you can use the keyword super to bypass the overloaded version in the class and invoke the version in the superclass: True or False? If false, explain why.

A - False. Should read override instead of overload. If your method overrides a method in its superclass, you can use the keyword super to bypass the overridden version in the class and invoke the version in the superclass.

Q - Write a Java application that meets the following specifications.

/*File SampProg14.java from lesson 38
Copyright 1997, R.G.Baldwin
Without viewing the solution that follows, write a Java
application that illustrates returning by value and by 
reference in Java.

Also cause your program to display a terminating message
with your name.

The output from the program should be:

Primitive value returned is 5
Value of instance variable in returned object is 10
Terminating, Dick Baldwin
**********************************************************/
class NewClass{//obj of this class will be returned by ref
  int instanceVariable = 10;
}//end NewClass

class SampProg14 { //define the controlling class

  int returnValue() {//function which returns by value
    return 5; //return a primitive type by value
  }//end returnValue()

  NewClass returnReference() {//function returns by ref
    return new NewClass(); //return an object by reference
  }//end returnReference()

  public static void main(String[] args){ // main method
    SampProg14 obj = new SampProg14();//instantiate object
    System.out.println(
      "Primitive value returned is " + obj.returnValue() );
    System.out.println(
      "Value of instance variable in returned object is " +
       obj.returnReference().instanceVariable );
    System.out.println("Terminating, Dick Baldwin");    
  }//end main
}//End SampProg14 class.  Note no semicolon required

Q - Write a Java application that meets the following specifications.

/*File SampProg15.java from lesson 38
Copyright 1997, R.G.Baldwin
Without viewing the solution that follows, write a Java
application that illustrates passing primitive variables 
by value and passing objects by reference.

Provide a termination message with your name.

The output from running this program should be:

In main
Value of primitiveVariable is 200
Value contained in ordinary obj is 100
In function passVariables
Value of primitiveVariable is 200
Value contained in ordinary obj is 100
Modifying values of arguments
Still in function passVariables
Value of primitiveVariable is 201
Value contained in ordinary obj is 101
Back in main
Value of primitiveVariable is still 200
Value contained in obj is now 101
Terminating, Dick Baldwin
**********************************************************/
//class used to instantiate a reference obj
class NewClass{ 
  int instanceVariable = 100;
}//end NewClass

class SampProg15 { //define the controlling class

  //function used to illustrate argument passing
  void passVariables(int primVar, NewClass refVar){
    System.out.println("In function passVariables");
    System.out.println(
      "Value of primitiveVariable is " 
      + primVar);
    System.out.println(
      "Value contained in ordinary obj is " 
      + refVar.instanceVariable);

    System.out.println("Modifying values of arguments");
    refVar.instanceVariable = 101;
    primVar = 201;  

    System.out.println(
      "Still in function passVariables");  
    System.out.println(
      "Value of primitiveVariable is " 
      + primVar);
    System.out.println(
      "Value contained in ordinary obj is " 
      + refVar.instanceVariable);
  
  }//end function passVariables

  public static void main(String[] args){ //main method
    //instantiate object for dispatching methods
    SampProg15 anObject = new SampProg15();
  
    NewClass obj = new NewClass();//ordinary object
    int primitiveVariable = 200;  //primitive variable

    System.out.println("In main");
    System.out.println(
      "Value of primitiveVariable is " 
      + primitiveVariable);
    System.out.println(
      "Value contained in ordinary obj is " 
      + obj.instanceVariable);

    //call method
    anObject.passVariables(primitiveVariable,obj);

    System.out.println("Back in main");
    System.out.println(
      "Value of primitiveVariable is still " 
      + primitiveVariable);
    System.out.println("Value contained in obj is now " 
      + obj.instanceVariable);
    System.out.println("Terminating, Dick Baldwin");

  }//end main
}//End SampProg15 class.  Note no semicolon required

Q - Write a Java application that meets the following specifications.

/*File SampProg16.java from lesson 38
Copyright 1997, R.G.Baldwin
Without viewing the solution that follows, write a Java
application that illustrates use of the "this" keyword to 
access an instance variable that is hidden by a local
variable.

Provide a termination message with your name.

The output from this program should be:

Local variable myVar contains 10
Instance variable myVar contains 5
Terminating, Dick Baldwin
===========================================================
*/

class SampProg16 {
  int myVar;  //instance variable named myVar

  public SampProg16(){myVar = 5;}//constructor

  void myFunction(int myVar){ //function w/arg named myVar
    System.out.println("Local variable myVar contains " 
      + myVar);
    System.out.println("Instance variable myVar contains " 
      + this.myVar);
  }//end myFunction

  public static void main(String[] args){ //main method
    SampProg16 obj = new SampProg16(); 
    obj.myFunction(10); //use it to call the method
    System.out.println("Terminating, Dick Baldwin");
  }//end main method
}//End SampProg16 class definition.

Q - Write a Java application that meets the following specifications.

/*File SampProg17.java from lesson 38
Copyright 1997, R.G.Baldwin
Without viewing the following solution, write a Java
application that illustrates use of super keyword to 
access the constructor in a superClass.  Also illustrate
the use of the super keyword to disambiguate a local 
variable from an instance variable in the superClass.

The output from this program should be:

In superClass constructor. Setting superClassData to 100
In subClass constructor. Setting subClassData to 200
In main
Instance var in superClass contains 100
Instance var in subClass contains 200
In function myFunc
Value of local superClassData var is 300
Value of instance var named superClassData is 100
Terminating, Dick Baldwin
**********************************************************/
class superClass{
  int superClassData;

  public superClass(){//superClass constructor
    System.out.print("In superClass constructor. ");
    System.out.println("Setting superClassData to 100");
    superClassData = 100;
  }//end superClass constructor

}//end superClass definition

class SampProg17 extends superClass{
  int subClassData;

  public SampProg17(){ //subClass constructor
    super(); //call superClass constructor
    System.out.print("In subClass constructor. ");
    System.out.println("Setting subClassData to 200");
    subClassData = 200;
  }//end subClass constructor

  //Function to illustrate use of super to disambiguate 
  // local variable and instance variable with same name
  void myFunc(){ 
    //create var to hide superClass instance var
    int superClassData = 300; 
    System.out.println("In function myFunc");
    System.out.println(
      "Value of local superClassData var is "
      + superClassData);
    System.out.println(
      "Value of instance var named superClassData is "
      + super.superClassData);
  }//end function myFunc

  public static void main(String[] args){ //main method
    //instantiate an object to dispatch method calls
    SampProg17 obj = new SampProg17();
    System.out.println("In main");
    System.out.println(
      "Instance var in superClass contains " 
      + obj.superClassData);
    System.out.println(
      "Instance var in subClass contains " 
      + obj.subClassData);

    //Call method to illustrate use of super 
    // to disambiguate local variable and instance 
    // variable with same name
    obj.myFunc();
    System.out.println("Terminating, Dick Baldwin");
  }//end main method
}//End SampProg17 class definition.

-end-