I'm working through a past exam for a computer science paper and have become slightly confused on this part here.
The instructions are to write a class book(done), which has two data fields(also done) a constructor which initializes the two values (done as well) and a constructor which replaces the default constructor (no clue what this is about). I've researched it and gone through my lab notes but I can't understand what they're asking.
Here's the code
public class Book{
//here's the two data fields
int pages;
String title;
public Book (int pageNum, String titleString){//here's the constructor to set the values
pages = pageNum;
title = titleString;
}
}
//so where's the other constructor that replaces the default constructor supposed to go?
I think following points mean same thing, which you have already done.
1.which has two data fields(also done) a constructor which initializes the two values
2.constructor which replaces the default constructor (no clue what this is about)
By default class has default constructor. like this
public Book()
{
}
If write some parameterised constructor, then default constructor will be replaced. By seeing through your code , you have already written parameterised constructor.
It seems they want something like this :
public Book() {
this(0, "");
}
Related
Okay. I'm fairly new in this Java thing, but i'm desperately trying to learn. I've come upon somewhat of a deadend. I'm making an inventory program as part of school and i have a superclass Items with 4 instance variables. No problem there. I have 4 subclasses, two of which is mandatory Food class, which have a futher 2 variables and Nonfood class, which have one more variable. My problems is this.
Right now i'm working with an ArrayList (this is what i know so far) but i'm seriously considering working with a map or a linkedMap.
I have based my ArrayList on my superClass Items, but i'm having trouble getting my subclass variables into my ArrayList. Any idea how that's done. Using relative simple solutions (remember i'm new at this)
I have not yet got my id working. I've, in the spirit of the shop terminology, called it barCode. It's part of my Superclass, and i can't seem to initialize it in my main class.
//constructer from superclass
public Items (int barCode, String itemName, String itemSupplier, double itemPrice, int stock)
{
this.itemName = itemName;
barCode = GenerateBarCode();
this.itemSupplier = itemSupplier;
this.itemPrice = itemPrice;
this.stock = stock;
// getter method for barCode
protected int getBarCode()
{
return barCode;
}
// method for generating barcode
private int GenerateBarCode()
{
Random barCode = new Random();
int barCode1 = barCode.nextInt(100000);
return barCode1;
}
If any more code i needed, let me know. I'm working on getting it a bit prettyer.
You have a local variable barCode in your constructor, and it is hiding your instance member also called barCode. Parameters are really local variables, and locals get precedence over fields. This local variable gets the random value, and then disappears at the end of the constructor, like all locals, leaving your field also called barCode with its original value.
You could fix it by changing the parameter to be called barCodeIn, or changing the statement to this.barCode = GenerateBarCode()
However the real solution is to remove the barCode parameter from the items constructor.
Since you are generating it with the GenerateBarCode() function, you don't really need to pass it in from the outside.
I was able to pass a secret test with my code, which essentially test the code with certain input and expected output. I kept getting an assertion error which stated, expected<1> but was:<0> Until I changed the code from this:
public Gunner(){
this.gunpower = 1;
this.GunnerStrength = 1;
this.name = "Default Gunner";
}
to
public Gunner() {
this("Default Gunner", 1, 1);
}
To illustrate further and to give reference points, here are the codes which preceded the above code:
package ship;
public class Gunner {
private String name;
private int gunpower;
private int GunnerStrength;
private int maxGupower;
private int maxGunnerStrength;
private int currentGunpower;
private int currentGunnerStrength;
public Gunner(String l_name, int l_gunpower, int l_GunnerStrength) {
this.name = l_name;
this.currentGunpower = maxGunpower = l_gunpower;
this.currentGunnerstrength = maxGunnerStrength = l_GunnerStrength;
}
public Gunner(Gunner other) {
this.name = new String(other.name);
this.gunpower = new Integer(other.gunpower);
this.GunnerStrength = new Integer(other.GunnerStrength);
this.maxGunpower = new Integer(other.maxGunpower);
this.maxGunnerStrength = new Integer(other.maxGunnerStrength);
this.currentGunpower = new Integer(other.currentGunpower);
this.currentGunnerStrength = new Integer(other.currentGunnerStrength);
}
}
If someone could please explain the differences between the two codes above it would be much appreciated.
Your original Gunner() constructor attempted to duplicate the logic of the Gunner(String,int,int) constructor, although apparently (as you've passed whatever the "secret test" was), it failed to do so correctly since it filled in different fields: It initialized gunpower, GunnerStrength, and name; but the other constructor initializes name, currentGunpower, maxGunpower, currentGunnerStrength, and maxGunnerStrength. That's quite a different set of fields.
Your revised Gunner() constructor reuses the logic of the Gunner(String,int,int) constructor, rather than attempting to duplicate it. And so it fills in the fields that Gunner(String,int,int) fills in. Presumably the test expected those fields to be filled in.
In general, duplicating logic is a bad idea, because inevitably things change over time, so unless there are convincing arguments to the contrary, reusing rather than duplicating logic is the way to go.
Re your edit:
I kept getting an assertion error which stated, expected<1> but was:<0>
The default value of an int field is 0, so if you don't initialize or assign another value to the field, it will have the value 0. So presumably the unit test was checking the value of one of the fields your original Gunner() didn't fill in (currentGunpower, maxGunpower, currentGunnerStrength, or maxGunnerStrength) but your new Gunner() does fill in (via Gunner(String,int,int)).
Side note:
Difference between using these two default constructors?
There are no default constructors in your code. A default constructor is provided by the compiler if you don't define any constructors for the class. Since you do define constructors for the class, there is no default constructor.
Your Gunner() constructor is a constructor with no formal parameters, sometimes called a zero-params constructor or a zero-args constructor or a no-arg(s) constructor (Java uses "parameter" rather than "argument" to refer to the things you pass into methods and constructors, but they're also commonly called "arguments" informally, hence "args").
This question already has answers here:
Can someone explain a void return type in Java?
(5 answers)
Closed 6 years ago.
I'm confused about "void",
as it pertains to methods.
I don't know what the distinction between two methods is when one has "void" and another doesn't.
For example, if I do:
Public meth (int amount)
{
amount = initial * interest;
return amount;
}
( not sure if it was right, or even valid, to take the name "amount" and name it the same thing as my formal parameter, but what makes sense here is that you're performing a calculation and returning the result)
Then, if I did something like:
Public void Testing (int array[])
{
//code that would modify the internals of an array
}
Would the second one have no "return" because it's more of a general method, that can be applied to any integer array, while the first one is about doing work on specific variables?
Would also appreciate one or two more examples of when I would or wouldn't be using "void" and "return".
One other thing that seems to confuse me is calling methods.
I know sometimes I'll do something like, for example, using the Testing method above,
Testing(ArrayName);
Other times, it will be like:
NameOfWhateverImApplyingMethodTo.MethodName();
And then there are times when things will be done properly by:
Thing1.MethodName(Thing2);
Which circumstances would I switch the syntax for method calls like this?
Java is case sensitive, so the modifier Public is invalid, use public
You can't define a method as public methodName(int a), only a constructor has this signature, a method must be public void methodName(<signature>) for methods that don't return anything or public <return type> methodName(<signature>) for methods that do.
Void basically means that the method will not return anything.
If you did
String name= "tim";
public void getName(){
return name;
}
This would result in an error, because the getName method is returning a string object called name, but the method declaration is saying I am returning nothing - because it is void.
Instead the method should be :
String name = "tim";
public String getName(){
return name;
}
Now when the method getName() is called it will return a string object "name" with "tim" inside of it :)
You might have void for a set method. So for example
String name = "tim";
public void setName(String newName){
this.name = newName;
}
When this method is called you would use setName("Andy"); and it would set the value of the name variable to be "Andy". Nothing is returned in this method, because it is setting something, but there is no need to send anything back, so we use void on the method declaration.
Hope this helps.
The method that has void as return type does not return anything. For example you want to set a field firstName in your class. You will write a setting method like
public void setFirstName(String n) {
this.firstName = n;
}
As you can see you are just setting a class variable and does not require to return anything.
If you dont use void then you have to provide a return type for method. Like if you wish to write a getter for above variable as:
public String getFirstName() {
return this.firstName;
}
Once you provide a return type, you will have to return a value of that type otherwise your code will not compile.
Calling a method can be done based on where you are calling it from and what modifier is used:
If you are calling the method from the same class then you can simply write firstName = getFirstName()
If you are calling the method from another class then you require object of method's class as qualifier like personObject.getFirstName()
If you are calling a static method then you require class name as qualifier like Person.getFirstName();
Return type is what you get out of it. When you call it, what are you hoping to get back? For instance, if the method gets the average of two numbers, then you're expecting a number back, so the return type will be a number type, like "int" (integer).
You can see what it should be using that logic or by looking in the method for the word return - what comes after return is what is returned, and its type should be declared in the method (e.g. if it says "return 4;" it's returning an int, and should be e.g. public int getFour()
You also asked about e.g. testing() vs testing(word)
I remember having the same difficulty. The distinction between the two also relates to the method declaration line. I'll illustrate.
public String testing(){
return "a word";
}
Calling this method by doing "System.out.println(testing());" should print "a word". Calling this method by doing "System.out.println(testing("a word"));" will give you an issue - this is because when you call testing, it looks at the appropriate method: one in the right class, with the right return type and with the right arguments/parameters. If you're calling testing("a word"), that means you're using a String as an argument (because "a word" is a string), and so it tries to use the testing(String aString) method - which doesn't exist.
So you use empty brackets when the method takes no input, and you put stuff in brackets when the method expects stuff. This should be less confusing than it sounds, because it's usually logical - if you want to call a method that returns an average, you need to ask yourself "Average of what?" You'd probably need to supply it with the values you want the average of.
Moving on: (a) testing() versus(b) AClass.testing() versus(c) aclass.testing() -
In (a), there's no class specified. Therefore, if you call it from that class, Java can guess which class: this one, and it'll work. From any other class, it won't know what you're talking about, and might even insult you.
In (b), you're specifying a class in general - therefore it'll know what class to find it in - and it'll work if it's a "static method". *[see bottom]
In (c), you're specifying an instance of AClass you want to run "testing()" on*.
For instance, imagine you've created a class called Business. You make a hundred Business objects by specifying for each a name, number, address.
e.g.
Business b = new Business(name, number, address);
Then in the Business class you have a method "getName()". This method takes no argument - you could see that the brackets are empty - so if, from another class, you call "Business.getName()", how could it know which name you want? You've just made a hundred businesses!
It simply can't. Therefore, for such a method, you'd call "b.getName()" (b being the Business we created above) and it would get the name for this instance of a Business - namely, b.
I'm happy to help, so if you're confused about any particular parts of what I just wrote please let me know and I'll try to elaborate!
edit: A bit on static methods:
Static methods don't belong to an instance of the class. getName(), for example, would get the name of this Business - ie, this instance of the Business class. But let's say that in the Business class you made a method that took the first letter of each word in a String and transformed it to uppercase - like if you wanted to make the business names look more professional when you printed them out.
public static String stringToUpperCase(String aString){
aString = aString.substring(0, 1).toUpperCase() + aString.substring(1);
return aString;
}
And to use that, you change the getName() method from:
public String getName(){
return name;
}
to
public String getName(){
return stringToUpperCase(name);
}
The new method is used here to make the name have an uppercase first letter - but that is the extent of its involvement with the Business class. You notice it doesn't ask for information about the name, address, or number for a particular business. It just takes a string you give it, does something to it, and gives it back. It doesn't matter whether you have no Businesses or a hundred.
To call this method, you'd use:
System.out.println(Business.stringToUpperCase("hello"));
This would print Hello.
If it were not a static method, you'd have to make a new Business first:
Business b = new Business("aName", "aNumber", "anAddress");
System.out.println(b.stringToUpperCase("hello"));
And if the method did need access to more Business-instance information (like a business's name number or address) it wouldn't be able to be an instance variable.
The first example, a method without a return type at all, is a constructor; used when an instance is created with new. However, you can't return a value from a constructor. Something like,
this.amount = initial * interest; // return amount;
Sets the field amount to initial * interest.
Ok I am trying to wrap my head around this:
Write an application that creates a class for the student object with the following attributes:
Student Number, Name, Address, Phone No., and Course.
Write a test program that sets and gets each attribute in the class.
The test program should also display all of the attributes in the class.
Using the student class and its attributes from the previous question, write an application (extend the previous program) that includes both a user-defined and default constructor.
Write a test program to demonstrate the use of both constructors.
This is a work-sheet from college, for some revision on Objects in Java.
The part that troubles me is the one where it asks to have both user-defined and default constructor?
I was under impression it was impossible to do it? Because if you don't provide a constructor yourself, JVM will provide one (default constructor?). But if you define any constructor, then default one becomes unavailable?
Is this just poorly worded task, or could it mean something else?
I'm pretty sure whoever created the work-sheet meant "No-arg constructor" instead of "Default constructor".
You can't technically create the Default constructor (since this is done for you by the compiler), but you can explicitly create the no-arg constructor (which functionally is the same).
So, yes, poorly worded task.
In java, when you don't explicitly specify a constructor, the compiler will add a "default" constructor: a constructor thar doesn't take parameters. If you specify a constructor, then the compiler doesn't add that constructor.
For instance, this code will compile fine:
class Student {
String name;
int age;
// ...
}
// ...
Student myself = new Student();
But this code wont compile:
class Student {
String name;
int age;
// ...
public Student(String name) {
this.name = name;
}
}
// ...
Student myself = new Student(); // compilation error: use new Student("Jhon Smith");
Because the default constructor is not available any more.
Java provide default constructor when you dont implement yourselve one. But when you create customized constructor you have to implement also default if you would like to use constructor with no arguments. Let's asume we have class A{} for java it will looks like that:
public class A{
public A(){//auto generated constructor
}
}
but if you provide an customized constructor auto generated constructor dissapear.
Default constructor is not created when programmer provides any constructor. But here I'm expecting that the author of this task understands "default" constructor as the one without any parameters.
Concluding you would have two constructors:
public class MyClass {
public MyClass () {
}
public MyClass (long studentNumber, String name, String address....) {
}
Above is correct, however, in OO terms, "default constructor" is a constructor that takes in no arguments. The other type of constructor is one where arguments are taken into the constructor to make things custom.
ie:
Student(){ //default constructor
number = 0;
name = "bob";
//etc etc
}
student(int nm, int nm, etc etc){ //parametrized constructor
number = nm;
name = nm;
//etc etc
}
According to Charatan & Kans, Java in Two semesters 3rd Edition, page 196:
Constructor just like any methods can be overloaded, meaning within a single class we can have 2 or more constructors, where one take 1 argument like:("studentName") and within the same class, another constructor might take 2 arguments ("studentName", " studentId"), yet another constructor still within the same class may have 3 arguments ("studentName", "studentId", " studentPhoneNumber").
This is Constructor Overloading. Here's an example:
public class student {
// attributes
private String studentName;
private int studentID;
private int studentPhoneNumber;
// constructor with one argument
public student (String studentNameIn) {
studentName = studentNameIn;
}
// constructor with 2 arguments
public student (String studentNameIn, int studentIdIn) {
studentName = studentNameIn;
studentID = studentIdIn;
}
// constructor with 3 arguments
public student (String studentNameIn, int studentIdIn, int studentPhoneNumberIn) {
studentName = studentNameIn;
studentID = studentIdIn;
studentPhoneNumber = studentPhoneNumberIn;
}
// default constructor REINSERTED no argument
public student () {}
// methods
}
The above is a clear example of constructor overloading. Now during the OBJECT creation, meaning when the student object is being created, it will be up to the programmer to utilise the constructor he/she chooses, with 0 arguments ( default that was REINSERTED) or with 1 argument again he/she may choose the constructor that contains 2 arguments etc. Its a matter of choice and requirement of user.
No superclass or multiple class is needed as constructor can be overloaded as demonstrated above.
This question already has answers here:
How to avoid constructor code redundancy in Java?
(4 answers)
Closed 9 years ago.
Hi I am just learning about constructor chaining in Java and had some questions...
First of all could someone please explain when I would ever need to use this? Off the top of my head I seriously cannot think of a situation.
In this example, within the constructor with no arguments I call another constructor. How do I access this new "James Bond" object for future use?
import java.util.*;
class Employee
{
private String name;
private double salary;
public Employee()
{
this("James Bond", 34000);
}
public Employee(String n, double s)
{
name = n;
salary = s;
}
public String getName()
{
return name;
}
public double getSalary()
{
return salary;
}
public static void main(String[] args)
{
Employee a = new Employee();
}
}
Actually I believe the most common use of chained Constructors is when the Constructor does more than just setting the member variables.
static int numOfExamples = 0;
public Example(String name, int num)
{
this.name = name;
this.num = num;
numOfExamples++;
System.out.println("Constructor called.");
Log.info("Constructor called");
}
public Example()
{
this("James Bond",3);
}
That way we don't have to write the code for logging and incrementing the static variable twice, instead just chaining the constructors.
Chaining constructors like this is useful to avoid repeating code, and helps with maintainability:
public MyClass(int x, double y, String z) {
// set fields
}
public MyClass() { // i.e. a constructor that uses default values
this(42, 4.2, "hello world"); // x is 42, y is 4.2, and z is "hello world"
}
If we didn't use the chain, and wanted to change how the x argument (for example) is processed when constructing an instance of MyClass, we would have to change code in both constructors. With the chain, we only need to change one of them.
1) As others have said, it's for code maintenance, basically the idea is that you only write one piece of code once, which means you only need to edit it once, there is no risk of overlooking something when editing your methods and the two accidentally becoming different.
Personally I tend to use this differently than in your example. Like so:
Employee() {
setupStuff();
}
Employee(String name) {
this();
this.setName(name);
}
This is a nice way of doing things, because potentially your setter can be way more complicated than just setting a member in the class. So basically what this does is puts calling the empty constructor and then a setter into a single method, making it much easier for anyone using the class.
2) The constructor being called doesnt't create a different object at all, it creates this object. Note that there is no new keyword used. Basically you're just calling a different method inside your constructor, except that method happens to also be a constructor.
Every time you want to allow constructing an object wit default values, and also want to allow creating the same object with non-default values. Let's imagine a DateTime class. You could want to initialize it with the current time by default, or with a specific time. Imagine a Car class. You could imagine constructing it with Black as the default color, or with a specific color. This kind of situation is very common. See java.util.ArrayList or java.util.Locale, for concrete examples.
It's stored in the name field. So you access it, from the object itself, with this.name (this being optional, just as in the getName() method).
How do I access this new "James Bond" object for future use?
Because you saved the values of name and salary as fields of your employee class, then inside the employee class you can use those fields, and outside your employee class you can use the getter/setter methos of your employee class