Old version
This is the CS 112 site as it appeared on May 12, 2023.
Problem Set 4 FAQ
If you don’t see your question here, post it on Piazza or come to office hours! See the links in the navigation bar for both of those options.
Part I
-
In problem 1, how can the
MovingVanconstructor check for bad values for the inherited fields if it needs to call the superclass constructor on the very first line?When your
MovingVanconstructor calls the superclass constructor, that other constructor will take care of the necessary error-checking of the values passed in for the inherited fields, and thus theMovingVanconstructor doesn’t need to perform any error-checking on those fields. (Note: TheVehicleclass we have provided doesn’t actually perform any error-checking on things like the make and the model, but you don’t need to try to correct for this failing.)Then, after calling the superclass constructor, the
MovingVanconstructor can perform any necessary error-checking on the values for its new fields – the ones that are not inherited. -
In problem 3, there are two different calls to the
addmethod that both add a string literal"hey". Will those two strings be represented by the sameStringobject in memory, or will there be two separateStringobjects?It depends on the compiler.
In many compilers, if a program includes two different string literals that both represent the same string (i.e., that both contain the same sequence of characters), the compiler will use the same
Stringobject for both of them.However, not all compilers do this. Some of them would use a separate String object for every string literal.
For Problem 3, you may assume that the compiler is taking either approach.
By the way, if two strings are not both string literals (e.g., if one or both of them were read from the console), then they will definitely be represented using two separate
Stringobjects.
Problem 4
-
We are supposed to use our
Cardclass from PS 3 in this problem. What should we do if we weren’t able to complete a working version of that class?You can use a compiled version of our
Cardclass. We’ve provided the necessary guidance for doing so here. -
In Problem 4, I’m getting an error that says something like “Cannot make a static reference to the non-static method...” Do you know why I would be getting this?
Don’t forget that non-static methods need a calling object – i.e., an object that comes before the dot when you call the method.
When we call a static method from another class, we put the class name before the dot. However, this does not work for non-static methods. For example, you cannot write something like
Card.getValue(), becausegetValue()is a non-static method. Instead, you need to do one of the following:- Put a calling object before the dot – the object that you want
to operate on. For example, if
cis theCardobject whose value you need, you would writec.getValue(). - If the line you are writing is part of another non-static
method, and the method you are calling will operate on the same
object as the current method, you should use the implicit
parameter to call it:
this.getValue().
- Put a calling object before the dot – the object that you want
to operate on. For example, if
-
For Task 2 and/or Task 3, I’m getting an error that says that “
Scannercannot be resolved to a type”. What am I doing wrong?You need to import
java.utilat the top of the file. -
When I test my
Playerclass on my own machine, it works fine, but I’m failing a Gradescope test for thewantsHit()method. Do you know why this could be?Make sure that you do not create a new
Scannerobject in yourwantsHit()method. Instead, as the problem specifies, you must use theScannerobject that is being passed in as a parameter. Failure to do so will cause you to fail our tests. -
For Task 3, I’m having trouble writing the constructor. Do you have any suggestions?
You may find it helpful to look at two of our vehicle classes as a model.
For example, the
Truckclass extends theVehicleclass. And becauseTruckobjects only have one new field of their own, most of the fields in the new object are initialized by having theTruckconstructor call the constructor of the superclass. Next, theTruckconstructor initializes the one new field that is not inherited. You will need to take a similar approach in yourDealerclass.Also, don’t forget that the constructor in the superclass (the
Playerclass) takes one parameter. Thus, when you call that constructor at the start of your subclass constructor, you will need to specify a value for that one parameter. -
For Task 3, I have completed a partial implementation of my
ComputerPlayerclass, but I get a compiler error that says “Implicit super constructor Player() is undefined”. I don’t understand what I’m doing wrong.There are two possible explanations for this error:
-
You haven’t defined a constructor for
Dealeryet. As a result, the compiler is trying to create a default constructor that begins with a call to a no-parameter constructor of the superclass. And becausePlayerdoesn’t have a no-parameter contructor, the compiler issues an error. -
You aleady have a constructor for
Dealer, but you forgot to begin it with a call to the superclass constructor. If you omit this call, the compiler tries to add a call to a no-parameter constructor of the superclass. And becausePlayerdoesn’t have a no-parameter contructor, the compiler issues an error.
Once you have a
Dealerconstructor that begins with a call to the superclass constructor, this error should go away. -
-
For Task 3, I’m overriding one of the inherited methods. Inside the method, I’m trying to use one of the inherited fields, but the compiler is giving me an error message. How can I access the field?
Because the inherited field is declared to be
privatein the superclass, you can’t access it directly in the subclass. Instead, you need to use one of the methods provided in the superclass. -
For Task 3, I’ve implemented one of the
Dealermethods that overrides the method inherited fromPlayerclass, but it’s not being called when I run the program. Instead, the superclass version of the method is still being called. What am I doing wrong?First, make sure that you have changed the line in the
mainmethod ofBlackjack.javathat creates the object for the dealer, modifying it so that it uses the constructor from your new subclass instead of thePlayerconstructor.If this still doesn’t fix things, check the header of your new method. In order for it to be called, it must have the same parameters as the method inherited from the superclass. That way, you will override the inherited method, and you will be able to take advantage of polymorphism and dynamic binding, as intended.
If you give your new method a different parameter list, the method will not override the inherited method. Rather, it will overload that method, and it will not be called by the code that we have given you.
-
I’ve completed all of the tasks, and my
Blackjackprogram doesn’t have any compiler errors, but I’m getting an exception when I run the program. Do you have any idea of what might be wrong?Don’t forget that the backtrace that accompanies the exception tells you the line number of the line that threw the exception. Use that information to diagnose the issue – adding temporary
printlnstatements as needed to assist you in figuring out what is going on. -
When I try to run my code, I get an error saying that it can’t find one of the other classes – something that looks like this:
Exception in thread "main" java.lang.NoClassDefFoundError: ...Why is this happening?
This probably means that you haven’t properly followed the instructions in the Getting started section in Problem 4.
In particular, make sure that all of the files are in the same folder, and that you use the File->Open Folder menu option in VS Code to open the folder containing your files. Note that you MUST open the folder and not just open the individual files.
To make sure things are correctly configured, we recommend that you do the following:
-
Use File->Close Folder or File->Close Editor to close any open files in VS Code.
-
Shut down the VS Code program.
-
Make sure that all of your files are in the same folder.
-
Start up VS Code again.
-
Use File->Open Folder to open the folder containing your files.
-
As needed, click on the name of the file that you want to edit from the list of files in the Explorer Pane on the left-hand side of VS Code.
Some other things to check:
-
Make sure that your files do NOT include a package statement at the top. For example, if you see something like this:
package ps4; // remove this!
at the top of a file, you should remove it.
-
Make sure that the only
importstatements at the top of your file are forjava.util.*. All otherimportstatements should be removed.
-
Problem 5
-
Can we use any methods of the
Arraysclass in our work on this problem?No.
-
For some of the methods that we are being asked to add to the
ArrayBagclass, the problem indicates that we should take full advantage of the existingArrayBagmethods. Can you give an example of what that means?Consider the following
containsAllmethod from lecture:public boolean containsAll(ArrayBag other) { if (otherBag == null || otherBag.numItems == 0) { return false; } for (int i = 0; i < other.numItems; i++) { if (! this.contains(other.items[i])) { return false; } } return true; }
This method needs to determine whether all of the items in the
ArrayBaggiven by the parameterotherare present in the calledArrayBag(the one that is given bythis). As a result, we use aforloop that processes one item at a time in theother.itemsarray.To check whether
other.items[i]is in the calledArrayBag, we could in theory have used a nested loop that checked each of the items in thethis.itemsarray. But because the existingcontainsmethod already performs this operation for us, we simply make the appropriate call to that method!In a similar way, you should take advantage of existing methods when writing your
equalsandsubtractmethods.