CompSci-61B Lab 1c
Programmer-defined Classes

Instructor: Prof. Robert Burns

Java programs that do anything useful almost always involve programmer-defined classes. It is associated with an approach to programming that organizes data and code in a certain way. Java was intended to be used in this way, which is why Java is often referred to as an "object-oriented programming language". Actually, it's entirely possible to write Java programs that are not object-oriented, as we did in the previous labs. But those did not do anything useful!

So Java programmers usually define their own classes -- sometimes as a reusable utility, but more often as a specific solution. Classes "encapsulate" data values, and the code that is used to manipulate that data. The analogy to real life is any physical item that has some measurable state associated with it (like size, weight, or temperature), and actions that can be used to observe or modify physical attributes. In programming, the attributes are called "private data members" of a class. The actions that observe these attributes, either in raw form or in some translation or combination, are "accessors". The actions that modify these attributes are called "mutators". Together, accessors and mutators form what is called the "public interface".

Here's an example:

public class Animal // must be stored in "Animal.java"
{
  // the private data attributes -- not directly accessible outside the class
  private String name; // automatically initialized to null
  private Integer age; // automatically initialized to 0
  private Double weight; // automatically initialized to 0.0 

  // the public interface
  public void set(String name, Integer age, Double weight) // a mutator
  {
    this.name = name;
    this.age = age;
    this.weight = weight;
  }

  public void setName(String name) // a mutator
  {
    this.name = name;
  }

  public void setAge(Integer age) // a mutator
  {
    this.age = age;
  }

  public void setWeight(Double weight) // a mutator
  {
    this.weight = weight;
  }

  public String getName() // an accessor
  {
    return name;
  }

  public Integer getAge() // an accessor
  {
    return age;
  }

  public Double getWeight() // an accessor
  {
    return weight;
  }

  public String toString() // a special accessor
  {
    String buf = "This is a " + name;
    buf += ". It weights " + weight + " pounds"; 
    buf += ", and its age is " + age + " years.";
    return buf;
  }
}

With this class, the programmer can create Animal "objects", and associate attributes to them. To create an animal, use the statement Animal a = new Animal();. To create another animal, use the statement Animal b = new Animal();. To set an attribute, use a mutator like this: a.setAge(2);. To retrieve an attribute, use an accessor like this: Integer age = a.getAge(); What's special about toString is that you can use it in string concatenation: "a is " + a and in output statements like this: System.out.println(a).

Note that the numeric data types are written in their uppercase forms -- this is not necesary, but it's done to remain consistent with the String value. Also note that there is no "constructor". You only need a constructor if you need the private data members to be initialized to some value other than their automatic defaults.

Note that the mutators tend to have the "return type" void, while accessors' return types match the data value.

In order to use the class, there needs to be a main container somewhere, to contain the statements that create and manipulate objects. While it is possible to put main in the public class along with the accessors and mutators, it usually appears in separate ".java" files. This supports code reusability, because the class can be created and stored once, and used may times. As long as the class with the object attributes and public interface is in the same package as classes whose main refers to it, no "import" statement is needed. We'll get to that another time, avoiding the issue by placing our files all in the same folder.

Here's a second ".java" file that uses the "Aniumal" class:

public class Zoo
{
  public static void main(String[] args)
  {
    Animal a = new Animal();
    a.set("Zebra", 12, 350.0); // a 12-year-old zebra, weighing 350 pounds

    Animal b = new Animal();
    b.set("Aardvark", 2, 45.5);

    Animal c = new Animal();
    c.set("Lion", 8, 220.0);

    System.out.println("Zoo inventory, 2007:");
    System.out.println(a);
    System.out.println(b);
    System.out.println(c);
    System.out.println(); // skip a line

    System.out.println("Projected zoo inventory, 2008:");
    c.setWeight(c.getWeight() + b.getWeight()); // the lion ate the aardvark
    a.setAge(a.getAge() + 1);
    c.setAge(c.getAge() + 1);
    System.out.println(a);
    System.out.println(c);

    System.out.println();
    System.out.println("The end");
  }
}

This assignment is worth 40 points, and consists of 4 exercises. Zero points will be awarded for programs with misspelled filenames, or incorrect case. Zero points will be awarded for programs that do not compile. Partial points will be awarded for programs that are run but do not conform to all specifications, at the discretion of the grader. Be sure to complete both exercises and post the lab1c.jar before midnight of the due date, because there is a 5-point-per-day lateness penalty for late work. Check the course outline for due dates for lab assignments.



EXERCISE 1: The "Name" Class (10 points)
Write Name.java in package compsci61b.intro based on the listing in our Carrano textbook, in section 1.16. Use similar comment blocks as were demonstrated in previous labs, except that the command that run the program (beginning with "java ") are not needed.

Here are some exceptions to be applied:

Compile and jar, but do not run the program. Since the class has no main, it cannot be run -- there is no entry point! Also, store the files in the same folder that has your lab 1a and 1b files, so that when you build the ".jar" file later, it contains all the files from labs 1a, 1b, and 1c.

Do not post this version of lab1b.jar -- wait until you complete all exercises.



EXERCISE 2: The "MyFriends" Application (10 points)
Write MyFriends.java in package compsci61b.intro based on the "Zoo" listing above. Use similar comment blocks as were demonstrated in previous labs, including the "run" commands. In main, create at least 3 Name objects, and use the public interface to set attributes and retrieve them for output statements. Here are the detailed specs:

Compile, jar, and run the program. As above, store the files in the same folder that has your lab 1a and 1b files, so that when you build the ".jar" file later, it contains all the files from labs 1a, 1b, and 1c.

Do not post this version of lab1b.jar -- wait until you complete all exercises.



EXERCISE 3: The "Student" Class (10 points)
Write Student.java in package compsci61b.intro, using exercise 1 as a model. Here are the detailed specs:

Compile and jar, but do not run the program. Since the class has no main, it cannot be run -- but this will change!

To test the class, include a main inside the class itself, and not in a separate class. In main, create at least 10 Student objects, and use the public interface to set attributes and retrieve them for output statements. Here are the detailed specs, similar to those of exercise 2:

Compile, jar, and run the program. But do not post this version of lab1b.jar -- wait until you complete all exercises.



EXERCISE 4: The "CalStudents" Application (10 points)
Write CalStudents.java in package compsci61b.intro, using exercise 1 as a model. This is an application that reuses the "Student" class from exercise 3. Note that there will be 2 main's that refer to "Student" objects -- one in the class for testing (from exercise 3) and one for the application (exercise 4). But this is okay in Java, because the "run" command specifies in which class to look for the main to use. Here are the detailed specs:

The only difference between the "CalStudents" application and the test program from exercise 3, is that the objects references are to be stored in an array of object references, and not in separate reference variables. Also, since the object references are arrayed, loops can be applied. So after the modified code, with an object reference array instead of separate object reference variables, add code according to this specification:

Compile, jar, and run the program.

With your files from labs 1a and 1b, and from exercises 1 and 2 still in the package folder, complete exercise 3. Then when you recreate lab1c.jar, the files from all three labs will be in the single ".jar" file.

Post your lab1c.jar file to your student UNIX account for grading and credit.


[ Home | Contact Prof. Burns ]