- CourseSession
- Enrolling Students
- int
- Initialization
- Default Constructors
- Suites
- The SDK and java.util.ArrayList
- Adding Objects
- Incremental Refactoring
- Objects in Memory
- Packages and the import Statement
- The java.lang Package
- The Default Package and the package Statement
- The setUp Method
- More Refactoring
- Class Constants
- Dates
- Overloaded Constructors
- Deprecation Warnings
- Refactoring
- Creating Dates with Calendar
- Comments
- Javadoc Comments
- Exercises
Adding Objects
The add method is documented in the Java SDK API as taking an Object as parameter. If you click on the parameter Object in the API docs, you will see that it is actually java.lang.Object.
You might have heard that Java is a "pure" object-oriented language, where "everything is an object." [3] The class java.lang.Object is the mother of all classes defined in the Java system class library, as well as of any class that you define, including Student and StudentTest. Every class inherits from java.lang.Object, either directly or indirectly. StudentTest inherits from junit.framework.TestCase, and junit.framework.TestCase inherits from java.lang.Object.
This inheritance from java.lang.Object is important: You'll learn about several core language features that depend on java.lang.Object. For now, you need to understand that String inherits from java.lang.Object, as does Student, as does any other class you define. This inheritance means that String objects and Student objects are also java.lang.Object objects. The benefit is that String and Student objects can be passed as parameters to any method that takes a java.lang.Object as a parameter. As mentioned, the add method takes an instance of java.lang.Object as a parameter.
Even though you can pass any type of object to a java.util.ArrayList via its add method, you don't usually want to do that. In the CourseSession object, you know that you only want to be able to enroll Students. Hence the parameterized type declaration. One of the benefits to restricting the java.util.ArrayList via a parameterized type is that it protects other types of objects from inadvertently being added to the list.
Suppose someone is allowed to add, say, a String object to the list of students. Subsequently, your code asks for the list of students using getAllStudents and retrieves the String object from the list using the get method. When you attempt to assign this object to a Student reference, the Java VM will choke, generating an error condition. Java is a strongly typed language, and it will not allow you to assign a String to a Student reference.
The following changes to CourseSession (appearing in bold) will make the test pass:
class CourseSession { ... private java.util.ArrayList<Student> students = new java.util.ArrayList<Student>(); ... void enroll(Student student) { numberOfStudents = numberOfStudents + 1; students.add(student); } java.util.ArrayList<Student> getAllStudents() { return students; } }
A new field, students, is used to store the list of all students. It is initialized to an empty java.util.ArrayList object that is bound to contain only Student objects. [4] The enroll method adds the student to this list, and the getAllStudents method simply returns the list.
Figure 2.3 shows how CourseSession is now dependent upon the parameterized type java.util.ArrayList<Student>. Also, the fact that CourseSession
Figure 2.3 Class Diagram with Parameterized Type
The class diagram in Figure 2.3 is not normal—it really shows the same information twice, in a different fashion. The parameterized type declaration suggests that a single CourseSession has a relationship to a number of Student objects stored in an ArrayList. The association from CourseSession to Student similarly shows a one-to-many relationship.