Core Java 2 - Volume I - Fundamentals, 5th Ed.

Objects and Classes

Using Existing Classes | Building your Own | Static Fields and Methods | Method Parameters | Object Construction
Packages | Documentation Comments | Class Design Hints

Intro to Object Oriented Programming

I'm glossing over this fast.  If you don't know what encapsulation, inheritance, polymorphism or instance of an object mean then go grab the Core Java 2 book.  Suffice it to say that if you know C++ you know the basics of OOP so you're good.  Java doesn't really mess with any of the basic ideas of OOP (in fact it makes it harder to lapse back into structured programming) so if you know C++ just note the differences and write some code. 

One thing I did find useful was the following.  It notes the three characteristics of objects

Behavior - What can this object do (what methods?, what data?)

State - How does the object react when you apply these methods?

Identity - What makes this object different from other objects with the same state and behavior?

  These things are usually taken for granted, but it's good to think about these things.

Relationships between classes

Dependence (uses a)

Aggregation (has a)

Inheritance (is a)

  You'll get the hang of this later.  If your class methods manipulate another class object it's dependant on it to run correctly.  This ain't so good.  If a method of your class creates an instance of another class then it aggregates that class.  This sounds good at first but it causes some nasty problems.  If you inherit from a base class you take on the functionality of it and then add to it.  This is one of the tenets of OOP.

UML (Unified Modeling Language) has a bunch of different flow chart notation arrows for differing relationships.

OOP vs. Procedural or Structured programming 

Back in the day you'd set up global data and then unleash a bunch of functions on it to get the desired result.  Now, it wasn't as wild as it sounds.  Many of us were using OOP techniques without even knowing it, like data hiding, code reuse, and other things.  By using structs in C you can craft a program that very neatly adheres to all the basics of a good OOP design, but then Smalltalk became popular and in the second half of the eighties C++ reared it's head and we've been in OOP land ever since.  

Think of OOP as packaging your data and functions in a description file (a class) and then getting an instance (a real beast that acts like you told it to) of it to perform your tasks.  By keeping it simple and having your classes do only what relates to them (this was called modularization back in the procedural days) you can keep things neat and understandable.  It's more than that but this programmer has always considered OOP the grouping of functions and data.  Everything else (encapsulation, inheritance, polymorphism) are just features of this paradigm.

Then everyone figured out ways to cheat.  That's right cheat.  C++ lets you write a regular old structured program and use instances of classes more like data structures plus.  Encapsulation is a major feature of OOP, but everyone's data is usually public and friend functions solve that nasty "but I wanna do it my way!" problem.  Java is a strongly typed and structured OOP language and it's going to force a good deal of the "OOP cheaters" to repent.  This is a good thing because the benefits of using a true OOP style (code reuse, readability, and more of a "mimic the real world" methodology) are worth it.

Using Existing Classes

Before setting up your own class the book shows you how to use an existing one.  Piece of cake, but there are some subtle differences if you're a C++ programmer.  

Lets say your class is called Date and you want a Date object to work with.  You can't just do this

Date  D1;

That only sets up an object variable.  It's like a null pointer for lack of a better example.  Now that you have a variable you can give it an object by calling the constructor (We'll get to them in detail later) 

D1 = new Date();

You can do this all in one line with the following...

Date D1 = new Date();

and you're set.  Remember this difference!  In C++ the first command would give you a working object, Java doesn't work that way.  An object variable only refers to an object, it doesn't contain it!  When you create an object it's value is a reference to it that you assign to a variable.  You can have as many variables as you like refer to any one object.

Just think of object pointers in C++ and you'll be ok

Date birthday;  // Java

is like 

Date* Birthday; // C++

in C++.

The GregorianCalendar() class  -  we use this class to write a calendar prog.  They talk about accessors and mutators and then write this nifty little program.

package MyJava;

import java.util.*;

public class CalendarTest
{
    public static void main(String[] args)
    {
        // construct d as current date
        GregorianCalendar d = new GregorianCalendar();
        
        int today = d.get(Calendar.DAY_OF_MONTH);
        int month = d.get(Calendar.MONTH);
        
        // set d to start date of the month
        d.set(Calendar.DAY_OF_MONTH, 1);
        int weekday = d.get(Calendar.DAY_OF_WEEK);
        
        // print heading
        System.out.println("Sun Mon Tue Wed Thu Fri Sat");
        
        // indent first line of calendar
        for (int i = Calendar.SUNDAY; i < weekday; i++) 
           System.out.print("    ");
        
        // Now start up the calendar loop
        
        do
        {
            // print day
            int day = d.get(Calendar.DAY_OF_MONTH);
            if ( day < 10 ) System.out.print(" ");
            System.out.print(day);
            
            // Mark the current day with a star *
            if (day == today) System.out.print("* ");
            else System.out.print("  ");
            
            // start a new line after every Saturday
            if ( weekday == Calendar.SATURDAY ) System.out.println();
      
            // advance d to the next day
            d.add(Calendar.DAY_OF_MONTH, 1 );
            weekday = d.get(Calendar.DAY_OF_WEEK);
        }
        while ( d.get(Calendar.MONTH) == month );  // loop ends next month
        
        // print a final end of line if nec
        if (weekday != Calendar.SUNDAY) System.out.println();
    }
} // eos

Try it.  It's pretty neat.

Building Your Own Classes

Very straightfoward.  Remember this shell...

class NameofClass
{
   constructor1 
   constructor2
   ...
   method1
   method2
   ...
   feild1
   feild2
   ...
}

And that's about it!  The example they use is a payroll system...

//  Page 133 of CJ2, 5th Ed.
//

package MyJava;
import java.util.*;
public class EmployeeTest
{
    public static void main(String[] args)
    {
        
        // create an array for the employees
        Employee[] staff = new Employee[3];
        
        // create them
        staff[0] = new Employee("Carl Cracker", 75000, 1987, 12, 15);
        staff[1] = new Employee("Harry Hacker", 50000, 1989, 10, 1);
        staff[2] = new Employee("Tony Tester", 40000, 1990, 3, 15);
        
        // now let's do stuff to em...
        for ( int i = 0; i < staff.length; i++) staff[i].raiseSalary(5);
     
        // now let's print it out
        for ( int i = 0; i < staff.length; i++)
        {
            Employee e = staff[i];
            System.out.println("name=" + e.getName() + " salary = " + e.getSalary() +  " Hireday = " + e.getHireDay());
        }
    }
}

class Employee
{
    public Employee(String n, double s, int year, int month, int day)
    {
        name = n;
        salary = s;
        GregorianCalendar calendar = new GregorianCalendar(year, month-1,day);
        // gregorian uses 0 for Jan
        hireDay = calendar.getTime();
    }
    
    public String getName()
    {
        return name;
    }
    
    public double getSalary()
    {
        return salary;
    }
    
    public Date getHireDay()
    {
        return hireDay;
    }
    
    public void raiseSalary(double byPercent)
    {
        double raise = salary * (byPercent / 100);
        salary += raise;
    }
    
    private String name;
    private double salary;
    private Date hireDay;
    
}  
        

Constructor, accessors, mutators, methods...pretty much the same as C++.  You can use multiple source files for classes, but you have to define a method INSIDE the class, not just declare it.  Constructors only run in conjunction with the new operator so when you throw that runtime error you'll know why.  All Java objects are constructed on the heap!  

You have the THIS implicit reference to the current object in JAVA!!

All methods of a class can access all data, private or not, in that class.  If you need to return an object from a method (I keep wanting to write function) then clone it first (deep not shallow) so you don't return a reference to a mutable object!

Static Fields and Methods

Same as C++.  Declare var as Static and then there's only one variable for all class objects.  Static Methods are so you can run a function without having an object or you want to have an accessor for a static field.  To call them you use the name of the class, not the object.

Here's a prog...

public class StaticTest
{
    public static void main(String[] args)
    {
        // fill a staff array with 3 people
        
        Employee[] staff = new Employee[3];
        staff[0] = new Employee("Tom", 40000);
        staff[1] = new Employee("Dick", 30000);
        staff[2] = new Employee("Harry", 75000);
        
        // print out their info....        
        for (int i = 0; i < staff.length; i++ )
        {
            Employee e = staff[i];
            e.setId();
            System.out.println("name= " + e.getName() + " Salary = " + e.getSalary() + " Id = " + e.getId() );
        }
        
        // call the static method
        
        int n = Employee.getNextId();
        System.out.println(" Next ID is : " + n);
     }
}

class Employee
{
    public Employee(String n, double s)
    {
        name = n;
        salary = s;
        id = 0;
    }
    
    public String getName()
    {
        return name;
    }
    
    public double getSalary()
    {
        return salary;
    }
    
    public int getId()
    {
        return id;
    }
    
    public void setId()
    {
        id = nextId;  // set id to the next id
        nextId++;
    }    
    
    public static int getNextId()
    {
        return nextId; // accessor for static var
    }    
    
    public static void main(String[] args)  // a tester method, I used it and it worked
    {
        Employee e = new Employee("Harry",75000);
        System.out.println("name = " + e.getName() + " Salary = " + e.getSalary() );
    }
 
    private String name;
    private double salary;
    private int id;
    private static int nextId = 1;
}   
    

That pretty much gets the point across...

Method Parameters

Important stuff!  Java doesn't ever pass by reference, always by value!!

A method cannot modify the actual variables passed to it.  How do I do a swap then?  Calm down.  It's only for primitives.  If you pass an object you can change a value, but you have to do it the OOP way and use the objects methods to make any changes.

Now, you may say that this is passing by reference, by the book authors and Java nuts say it isn't.  Why?  Well, if you did a swap the objects would come back unswapped because you use temporary variables in the function and they get swapped and the real objects don't change.  This is silly.  Of course you're passing by reference.  You just have to remember that you can't reassign ref names in a method!  You could do the swap if you (1.  called A's get, 2. stored it in a temp, 3. use B's get with the A set, and 4. then set B's with the temp value)...  Sorta like a deep swap.  Just remember that accessors act as assignments at this level.  Sheesh. True it's not classic pass by reference but if I can get to the object itself and alter it then that's all I need.  They say they pass object references by value.  Duh.  It's like passing a pointer.  The Java community doth protest too much on this one.. They just want to be different than C++...BUT they are correct in saying that a method cannot make an object variable refer to another object, so keep it in mind.

Object Construction

Object construction is pretty important so they devote a whole section to it. They point out that you can have overloaded constructors (Same name, different parameter list thus different signature).  They note that Java has default Field (Java word for variables) initializations, numbers to 0, booleans to false, and object references to NULL.  If you don't write a constructor for your class you'll get a default constructor that sets all your fields to the default values.

Most of the time you'll use explicit field initialization, either by using a passed in parameter or a value from another method in the class (assignId(), etc).  

Constructors can call other constructors.  (Like a one param constructor calling a two with the param and a fixed value)

You can also use an Initialization block.  It's just a block of code that gets run when the object is created.  It's rarely used or needed, but it comes in handy if you want to init a static var with a random number or other such stuff.

Here's some code on the subject...

// page 161 CJ2 
//
import java.util.*;

public class ConstructorTest
{
    public static void main(String[] args)
    {
        // fill the staff with 3 emps
        Emp[] staff = new Emp[3];
        staff[0] = new Emp("Harry", 75000);
        staff[1] = new Emp("Bob", 55000);         
        staff[2] = new Emp("Lars", 77500);
        
        // print out all of the Employee info
        for (int i = 0; i < staff.length; i++)
        {
            Emp e = staff[i];
            System.out.println("Name= " + e.getName() + " Id: " + e.getId() + " Salary = " + e.getSalary() );
        }
    }
} // eoc ConstructorTest

class Emp  // renamed to avoid "Employee.class" conflict in example directory
{
    // Three overloaded constructors comin up!!
    
    public Emp(String n, double s)
    {
        name = n;
        salary = s;
    }
    
    public Emp(double s)
    {
        //calls the first constructor...
        this("Employee#" + nextId, s);
    }
    
    // the default constructor
    public Emp()
    {
        // name inited to "" with vars
        // s inited to 0
        // id assigned in an initialization block
    }
    
    public String getName()
    {
        return name;
    }
    
    public double getSalary()
    {
        return salary;
    }
    
    public int getId()
    {
        return id;
    }
    
    // object initialization block
    {
        id = nextId;
        nextId++;
    }
    
    // class variables
    private String name=""; // init the var
    private double salary;
    private int id;
    private static int nextId;
 
    // static init block
    // <* Note - code appeared before var declarations in book but the 
    // compiler threw a "no forward reference" error.
    // somehow the static init block tried to execute before the 
    // vars were set up so I moved the code here and it runs like gangbusters
    
    static
    {
        Random generator = new Random();
        // set id to a random number between 0 and 9999
        nextId = generator.nextInt(10000);
    } 
}

See how the id var gets setup in the init block.  Like I said, rare but useful.

Now, and this is important, JAVA DOES NOT SUPPORT DESTRUCTORS.  They say that because Java does automatic garbage collection that you don't need them, but what if you want to do other clean up tasks?  

You create a method called finalize().  It gets run when your object is destroyed, but because you're never really sure when Java will destroy the object (Why we aren't sure is something they don't tell us). it's not a great answer either.   There used to be a call ("System.runFinalizersOnExit(true)") but this is unsafe and has been deprecated.  If you need to free up a resource immediately after using it you have to manage it yourself, the book recommends a dispose() method of your own creation for this dirty work.

Packages

Very similar to C++'s .h or .hpp files.  You can group your work, keep it in a package, and use the Java import command to tell the Java compiler where to look for the code.  This is different form C++ in that the #include actually includes the declaration code for classes and such because the C++ compiler isn't going to go looking for it.  The Java compiler  actually will look for code for you, as long as you tell it where to look.  The import doesn't "bring the code" to you, it just tells Java where to look.

The main Java libraries are all packages, java.util,  java.lang, java.net, etc.  javax is the same way.  

You don't have to use the import if you don't want to.  You can just type the whole path ( new java.util.Date() ) and you'll be fine.  This is how you handle possible name conflicts.  If you import two packages and they have a common class name just be sure to ask for the one you want explicitly.

If you want all the classes of a package use the * notation.  You can only do it for a single package though so don't bother trying to do this..

import java.*.*  //  we all try it. trust us, it don't work..

Just do this...

import java.util.*   //  I want all the util classes

A class can use all classes from it's own package and all public classes from other classes.

You can only import classes, not objects.  You can't import System.out for example...

If you're a C++ guy think of package and import as analogs of namespace and using.

To add a class to a package just put the package command at the top..

package myjava.mathstuff;

and see that the code, the .java, is in a subdirectory tree that matches the package name.  On my trusty Pentium 3 W2K box this code would go in the c:\..\myjava\mathstuff directory.  

I implore you to read the book for some gory details I'm not going to reiterate here, but they go into how the virtual machine finds files, archiving with jars, and stuff on package scope and package sealing (they ain't protected ya know, very fun).

Documentation Comments

I'm not going nuts on this here.   You can use the javadoc utility to pull comments out of your code to do automatic documentation for you.  You start a comment with /** and end it with */.  Then there's tags to use for special extractions like @version for a version number or @author to get my name and blame me for something.  Then there's hints on documenting packages (with .HTML in the package root dir).  This is for when you're coding, not learning.  Bag this stuff until later.

The Javadoc Doclet Overview

Class Design Hints

Real simple.  They list 7 and they're pretty much on point.  Hit the book for the details

  1. Always keep data private (encapsulation is key)

  2. Always initialize data (Don't rely on defaults, only trust yourself)

  3. Don't use too many basic types in a class (group when you can; street, city, zip should be an address class, not separate)

  4. Not all fields need accessors and mutators (be smart, don't waste time, will you ever change a hiring date?)

  5. Use a standard form and stick with it (do it your way, but be consistent)

  6. Break up classes with too much responsibility ( <-- big OOP design word there, modularization kids, KISS)

  7. Use descriptive names for classes, data, and methods (I want to untangle the spaghetti three years from now)

Now lets see how to save time and grab the usefulness of other classes......Inheritance...

Go back to the top

Send mail to lars@sorcon.com with questions or comments about this web site.
Copyright © 2004 Sorensen Consulting