:!: Please look at all my message it is not long as it seems. My question is at the end and thank you in advance.

Here is a small class called Record that is a utility class for the InventorySet class.
final class Record implements Comparable

{
  /**
   * The video.
   * <p><b>Invariant:</b> <code>video() != null</code>.</p>
   */
  VideoObj video;
  /**
   * The number of copies of the video that are in the inventory.
   * <p><b>Invariant:</b> <code>numOwned > 0</code>.</p>
   */
  int numOwned;
  /**
   * The number of copies of the video that are currently checked out.
   * <p><b>Invariant:</b> <code>numOut <= numOwned</code>.</p>
   */
  int numOut;
  /**
   * The total number of times this video has ever been checked out.
   * <p><b>Invariant:</b> <code>numRentals >= numOut</code>.</p>
   */
  int numRentals;
  /**
   * Initialize all object attributes.
   */
  Record(VideoObj video, int numOwned, int numOut, int numRentals) {
    this.video = video;
    this.numOwned = numOwned;
    this.numOut = numOut;
    this.numRentals = numRentals;
  }
  /**
   *  Return a copy of this record.
   */
  public Record copy() {
    return new Record(video,numOwned,numOut,numRentals);
  }
  /**
   * Delegates to video.
   * <p><b>Requires:</b> thatObject to be a Record.</p>
   */
  public boolean equals(Object thatObject) {
    return video.equals(((Record)thatObject).video);
  }

Now here is the InventorySet class

final class InventorySet {
  private Map _data;
  int thesize;
  InventorySet() {
    // TODO  
    _data = new HashMap();    
       }
  /**
   *  Return the number of Records.
   */
  public int size() {
    // TODO  
    thesize = _data.size(); 
    return thesize;
  }
  /**
   *  Return a copy of the records as a collection.
   *  Neither the underlying collection, nor the actual records are returned.
   */
  public Collection toCollection() {
    // Recall that an ArrayList is a Collection.
    // TODO 
    ArrayList list = new ArrayList();
    String val;
    Iterator i = _data.values().iterator();
    while (i.hasNext()) 
    {
      val = (String) i.next();
      list.add (val);
    } 
    Collection copyList = list;
    return copyList;
  }
    /**
   * Check out a video.
   * @param video the video to be checked out.
   * @throws IllegalArgumentException if video has no record or numOut
   * equals numOwned.
   */
  public void checkOut(VideoObj video) {
    // TODO  
       Object m = _data.get(video);
           if(m == null )  
    throw new IllegalArgumentException(); 
     _data.remove(video);    
  }

Now my question is: The professor wants us to throw an IllegalArgumentException in case there is no record or if numout is < 0. How can I access numOut a variable of the Record class if I don't have anything to allow me to create an object of the record class??
I even tried to do the following:

 Record c; Record r = c.copy();
if(m == null || r.numout < 0)  
    throw new IllegalArgumentException();

However i got a compilation error indicating that c might not have been initialized. Well, that is right. How can i access numout ??
Thank you for your help.
Dounia

Edited 3 Years Ago by happygeek: fixed formatting

Just taking a quick stab at it, but:
Record c; Record r = c.copy();
should be:
Record c = new Record(); Record r = c.copy();
This will initilize c to a new Record instance.

Hi,
Thank you Jerbo for trying. You cannot say the following:
Record c = new Record(); and then Record r = c.copy();

Record has a constructor with three parameters. Take a look again at the constructor.

Dounia

So? Use the proper constructor.
Do some of your own thinking man... You called a function on your variable c while that variable was not initialised, that was the message.

If you create a constructor with parameters, then you should also create a default constructor (without parameters.) In most cases Java does this automatically. But best coding practice is to always create a default constructor. Then you can use this to initialise the class when instantiated.

Or, initilize with the parameters:
Record c = new Record(myVideo, myNumOwned, myNumOut, myNumRentals);

If you create a constructor with parameters it is NOT mandated you create one without parameters.
I wonder where you got that idea?

Also, a default no-argument constructor is created if and ONLY if there is NO other constructor at all. The compiler will not add it if a constructor with arguments is available.

My Bad......
I was thinking of when you extend a class and you define a constructor with parameters.

From Tech Tip in my Java Book:
Remember that the compiler will only create the default no-arguments constructor if no other constructors are defined. If you define a constructor, be sure to include a no-arguments constructor even if it containes no code, so that your class can be subclassed.

Well, thank you Jerbo and Jwenting for your ideas. But it seems that none of you understood my problem. Yes I know that you have to create an object of a class in order to access any variable if it is not private and same for any method of that class.
Jwenting said: (So? Use the proper constructor.
Do some of your own thinking man... You called a function on your variable c while that variable was not initialised, that was the message.) Sorry, I am not dum. You should understand that the professor created these classes like you saw them and he did not give us the parameters needed for creating a Record. When we asked him about that he said think about it. That's why I asked for any help.

Dounia

Ok, I think I might understand you now.

I think you would need to do the following:

Record c = [B]new Record([/B]); 
        Record r = c.copy();

The reason for the 'c' not initialized, is because you only create a variable for 'c' of type Record. However the JVM only allocates memory for the object (but nothing is initilized.) You need to instaniate the object with the NEW keyword to create a functional object from the class. Once you have an instance of the class, you can work with its instance members.

That would at least take care of the variable not initilized. Now for the IllegalArgumentException. If I understand the rest, you should then have:

Record c = new Record(); 
        Record r = c.copy();
        if(m == null || r.numOut < 0) {
             throw new IllegalArgumentException();
        }

Since 'm' is representitive of "_data.get(video)" then I suspect it should work. However I am not familure yet with 'Map' as I am in a Java certification class myself. We haven't covered this yet.

My only other question is when you create a 'Record' object, will it always be initilized with your (VideoObj video, int numOwned, int numOut, int numRentals) set? If so then should you not either create a default constructor to set these, or at least define these when you create the object:

Record c = new Record(myVideo, myNumOwned, myNumOut, myNumRentals);

Another thing I though of, is should not the VideoObj (which I see no code for) not have these values? If so then you would initilize:

// Assumption  VideoObj myVideo = new VideoObj();
   Record c = new Record(myVideo, myVideo.numOwned, myVideo.numOut, myVideo.numRentals);

I am assuming that VideoObj is used to get the video information to be passed on to the Record().

Ok, Jerbo, enough already, I think I have analyzed this to much, and if so, I appoligize. :lol:

Anyway, I hope this helps, but I think I just beat on the same drum as before.

Another thing I just thought of. If you wish to force the use of parameters (in other words you don't want the developer to use the default constructor for Record,) then code the following default constructor in Record:

public Record() throws IllegalArgumentException {
            System.out.println("Must use: ");
            System.out.println("   Record(VideoObj video, int numOwned, int numOut, int numRentals)");
            System.out.println("when creating Record()");
            throw new IllegalArgumentException();
    }

Then if the user trys to code:

Record c = new Record();

They will get an exception with the explanation to use the parameter constructor.

Might that be part of what you are looking for?

:)
Hi Jerbo,
Thank you for taking time to analyze all this code. I appreciate a lot.
You cannot create an object of class with an empty constructor, if the constructor of that class has parameters. We already asked the professor about this and he said think about it. Finally, someone told me that since class Record is a utility for the InventorySet class then I should do the following:
The variable "m" contains a record object then i would need to cast it to a record, and then check its checkout values. I have already done the first part.

Then here is the changes to the method and it is working now:
public void checkOut(VideoObj video) {
// TODO
Object m = _data.get(video);
Record c = (Record)m;
if(m == null || c.numout < 0 )
{throw new IllegalArgumentException();
_data.remove(video);
}
}
Have a good day Jerbo and one again thanks a lot.
Dounia

This article has been dead for over six months. Start a new discussion instead.