Click to See Complete Forum and Search --> : How to join more than one class together?


blues
02-21-2005, 08:20 PM
Greetings.

I am trying to follow examples 10.12-10.17 in the fifth edition of Deitel's How to Program Java.

It starts out with the following code of using an abstract class. I have a basic understanding of what is happening.


public abstract class Employee
{
private String myFirstName;
private String myLastName;
private String mySocialSecurityNumber;

// constructor
public Employee( String first, String last, String ssn )
{
myFirstName = first;
myLastName = last;
mySocialSecurityNumber = ssn;
}

// set first name
public void setFirstName( String first )
{
myFirstName = first;
}

// return first name
public String getFirstName()
{
return myFirstName;
}

// set last name
public void setLastName( String last )
{
myLastName = last;
}

// return last name
public String getLastName()
{
return myLastName;
}

// set social security number
public void setSocialSecurityNumber( String number )
{
mySocialSecurityNumber = number; // should validate
}

// return social security number
public String getSocialSecurityNumber()
{
return mySocialSecurityNumber;
}

// return String representation of Employee object
public String toString()
{
return getFirstName() + " " + getLastName() + "\nSocial security number: " + getSocialSecurityNumber();
}

// abstract method overridden by subclasses
public abstract double earnings();

} // end abstract class Employee

Now the next section of code gets or retreives those classes (well, the only one I typed above).


// fig. 10.17: payroll system test
// employee hierarchy test program.

import java.text.DecimalFormat;
import javax.swing.JOptionPane;

public class PayrollSystemTest {

public static void main( String[] args )
{
DecimalFormat twoDigits = new DecimalFormat( "0.00 );

// create Employee array
Employee employees[] = new Employee[ 4 ];

// initialize array with Employees
employees[ 0 ] = new SalariedEmployee( "John", "Smith",
"111-11-1111", 800.00 );
// initialize array with Employees
employees[ 0 ] = new CommissionEmployee( "Sue", "Jones",
"222-22-2222", 10000, .06 );
// initialize array with Employees
employees[ 0 ] = new SalariedEmployee( "John", "Smith",
"111-11-111", 800.00 );
// initialize array with Employees
employees[ 0 ] = new SalariedEmployee( "John", "Smith",
"111-11-111", 800.00 );

String output = ""

// generically process each element in array employees
for ( int i = 0; i < employees.length; i++ ) {
output+= employees[ i ].toString();

// determine wheter element is a BasePlusCommissionEmployee
if ( employees[ i ] instanceof BasePlusCommissionEmployee ) {

// downcast Employee reference to
// BasePlusComissionEmployee reference
BasePlusComissionEmployee currentEmployee =
( BasePlusCOmissionEmployee ) employees[ i ];

double oldBaseSalary = currentEmployee.getBaeSalary();
output += "\nold base salary: $" + oldBaseSalary;

currentEmployee.setBaseSalary( 1.10 * oldBaseSalary;
output += "\nnew base salary with 10% increase is : $" +
currentEmployee.getaseSalary();

} // end if

output += "\nearned $" + employees[ i ].earnings() + "\n";

} // end for

// get type name of each object in employees array
for ( int j = 0; j < employees.length; j++ )
output += "\nEmployee " + j + " is a " +
employees[ j ].getClass().getName();

JOptionPane.showMessageDialog( null, output ); // display output

System.exit(0);

} // end main

} // end class PayrollSystemTest

My question is that how do you connect separate classes together to perform several functions inside a program?

Is it like writing a library package and then importing it?

sjalle
02-22-2005, 04:18 AM
If you want to use several classes in a program then these
classes must be in the same package as the program code, if
not you will have to import them.

If you by connect mean making a new class based on
two other classes, by inheritance then than is
impossible in java (thank God). So you cannot say like:

public class CClass extends AClass, BClass {
// blabla
}

If you want to use AClass and BClass in combination in
your own class CClass, in order to enhance the use of
these classes then you can do this in at least two ways:

Instantiate the AClass and the BClass inside your CClass.
This method is called making a wrapper class.

public class CClass { // <-extends nothing but java.lang.Object
BClass bClass=null;
AClass aClass=null;
public CClass (/*parameters*/) {
aClass=new AClass((/*parameters*/);
bClass=new BClass(/*parameters*/);
// now use the public methods in the two
// classes in this class like in the method below:
}
public int doSomething() {
int x=bClass.doSomeBStuff(); // <-use BClass method
int y=aClass.doSomeAStuff(); // <-use AClass method
return x*y;
}
}

Use inheritance; Extend AClass or BClass in your CClass
and instantiate the other one inside the CCLass.

public class CClass extends AClass {
BClass bClass=null;
public CClass (/*parameters*/) {
super(/*parameters*/); // call the AClass constructor
bClass=new BClass(/*parameters*/);
// now use the public methods of BClass and the
// inherited (public and protected) methods of AClass
// like in the method below
}
public int doSomething() {
int x=bClass.doSomeBStuff(); // <-use BClass method
int y=doSomeAStuff(); // <-use AClass inherited method
return x*y;
}
}


It gets a bit trickier when it comes to abstract classes.
The sole purpose of abstract classes is to be able to treat
the set of subclasses (extended from the abstract class) as
they where all instances the abstract superclass. The same
can be achieved by using a 'normal' class as a superclass,
except for a vital difference:

Take the example where you have multiple classes that are used for
drawing a gameboard on the screen; The screen is a JPanel extension
in which you have extended the paint() method, and this JPanel
will be rendering say, 3 different visual elements (classes).
They are MyCircle, MySquare and MyTriangle. They are all
descendants of the GameBoardElement class.
These elements are stored in an ArrayList that is looped over
during the paint process and the only method that the JPanel
is 'interested' in is these elements'
public void draw(Graphics g) method. If GameBoardElement
is a 'normal' class with this method defined, and the three
subclasses override this method, and you do like this in your
JPanel extension:


// Ex. A
// the elementList is an ArrayList containing a mixture of
// all three classes (MyCircle, MySquare and MyTriangle)
public void paint (Graphics g) {
for (int i=0; i<elementList.size(); i++) {
GameBoardElement ge=(GameBoardElement)elementList.get(i);
ge.draw(g);
}
}

..then the GameBoardElement class' draw(Graphics g) method
is invoked, and that is not what you want.
You could do like:'

// Ex B:
// the elementList is an ArrayList containing a mixture of
// all three classes (MyCircle, MySquare and MyTriangle)
public void paint (Graphics g) {
for (int i=0; i<elementList.size(); i++) {
GameBoardElement ge=(GameBoardElement)elementList.get(i);
if (ge instanceof MyCircle) {
MyCircle mc=(MyCircle)ge;
mc.draw(Graphics g)
} else if (ge instanceof MySquare) {
MySquare ms=(MySquare)ge;
ms.draw(g);
} else ....and so on...
}
}


If, on the other hand GameBoardElement is an abstract class and
the draw method is defined as an abstract method then the code
in Ex. A above will call the actual method of the subclass. This
'search' for the subclass method implementation is done at runtime,
not during compilation (as is the case w, the 'normal' subclass.