inheritance and objects in ArrayList - java

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.

Related

type error thrown when creating an array of object from an existing array

The following class has an array of integer
public class customers {
public static int ID[];
public customers(int ID[]) {
ID = new int[10];
ID[0] = 00245;
ID[1] = 76644;
// more
}
//getters and setters
The subclass is defined as follow
public class songs extends customers {
//bunch of fields
The issue rises when within my array of objects. To create it, the following constructor was needed
public songs(int ID, // bunch of fields {
super(ID[0]);
this.ID = ID[];
// bunch of fields
Here, the super() method throws me back an error, that int[] in customers cannot be defined as a simple int.
Same goes when populating my array :
arraylist.add(new songs(ID[0], ...)); // didnt paste other variables
ID[0] is considered a simple int and not a int[].
While I understand the error itself, I don't know what causes it nor how to make java use my array of customers within the arrayList of Object defined in songs.
Thanks in advance !
If you want to send an array through subclass constructor you must first have a non-static (instance) array field in your super class, like this:
private int[] ids;
Be noticed that in java the fields are usually defined in camel case format.
Also you have a syntax error in this line:
super(ID[0])
You are referencing the int parameter defined in songs constructor as if an array, that is not correct.
Your call on super(ID[0]); is wrong: it calls the constructor of your members class, sending to it an int rather than an int[] as specified by your constructor. Moreover, I believe this.ID = ID[]; is wrong as well: "ID[]" in this context doesn't represent anything.
Also, as mentioned, static is probably not the good approach: it means that all Objects of type "Members" will share the same one-and-unique attribute "ID[]"!
More code would help. Especially about your songs, and the "arraylist" you're talking about.

A Constructor to replace the default constructor?

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, "");
}

Difference between using these two default constructors?

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").

What's the point of get and set methods [duplicate]

This question already has answers here:
Set and Get Methods in java?
(16 answers)
Closed 8 years ago.
In my CS class I am just learning about classes and OOP.
So when you create a class you initialize a certain number of private variable.
I know you make them private because if they were public they would be easily changeable and could lead to a lot of bugs.
So we use get and set methods to change the variable. But that once again makes the variables very easy to change right? So whats the point of making them private in the first place?
Some benefits of using getters and setters (known as encapsulation or data-hiding):
1. The fields of a class can be made read-only (by only providing the getter) or write-only (by only providing the setter). This gives the class a total control of who gets to access/modify its fields.
Example:
class EncapsulationExample {
private int readOnly = -1; // this value can only be read, not altered
private int writeOnly = 0; // this value can only be changed, not viewed
public int getReadOnly() {
return readOnly;
}
public int setWriteOnly(int w) {
writeOnly = w;
}
}
2. The users of a class do not need to know how the class actually stores the data. This means data is separated and exists independently from the users thus allowing the code to be more easily modified and maintained. This allows the maintainers to make frequent changes like bug fixes, design and performance enhancements, all while not impacting users.
Furthermore, encapsulated resources are uniformly accessible to each user and have identical behavior independent of the user since this behavior is internally defined in the class.
Example (getting a value):
class EncapsulationExample {
private int value;
public int getValue() {
return value; // return the value
}
}
Now what if I wanted to return twice the value instead? I can just alter my getter and all the code that is using my example doesn't need to change and will get twice the value:
class EncapsulationExample {
private int value;
public int getValue() {
return value*2; // return twice the value
}
}
3. Makes the code cleaner, more readable and easier to comprehend.
Here is an example:
No encapsulation:
class Box {
int widthS; // width of the side
int widthT; // width of the top
// other stuff
}
// ...
Box b = new Box();
int w1 = b.widthS; // Hm... what is widthS again?
int w2 = b.widthT; // Don't mistake the names. I should make sure I use the proper variable here!
With encapsulation:
class Box {
private int widthS; // width of the side
private int widthT; // width of the top
public int getSideWidth() {
return widthS;
}
public int getTopWIdth() {
return widthT;
}
// other stuff
}
// ...
Box b = new Box();
int w1 = b.getSideWidth(); // Ok, this one gives me the width of the side
int w2 = b.getTopWidth(); // and this one gives me the width of the top. No confusion, whew!
Look how much more control you have on which information you are getting and how much clearer this is in the second example. Mind you, this example is trivial and in real-life the classes you would be dealing with a lot of resources being accessed by many different components. Thus, encapsulating the resources makes it clearer which ones we are accessing and in what way (getting or setting).
Here is good SO thread on this topic.
Here is good read on data encapsulation.
As the above comment states, getters and setters encapsulate (i.e. hide) inner details of your class. Thus other classes that interact with yours, do not need to know about the implementation details.
For example, in the simple case you describe, instance variables are exposed via getters and setters. But what if you wanted to change your class so that you no longer used instance variables, but rather you persisted the values to disk. You could make this change to your class without affecting the users of your class.
Keep in mind also that getters and setters need not always be provided. If you do not want your class to provide a way to set or read these properties, then don't. Simply make them private.
get is used to obtain a value for an attribute and set is used to put a value to an attribute
ex:
private int variable;
public int getVariable(){
return variable;
}
public void setVariable(int aux){
variable=aux;
}
In general, is used to encapsulate an attribute.
reference:
Set and Get Methods in java?
Encapsulation or data hiding gives u more control on what values can be set to a field. Here is an example if you don't want a class attribute to have a negative value:
class WithoutGetterSetter {
public int age;
}
class WithGetterSetter {
private int age;
public setAge(int age) {
if(age < 0)
// don't set the value
else
this.age = age;
}
}
public class testEncapslation {
public static void main(String args[]) {
WithoutGetterSetter withoutGetterSetter = new WithoutGetterSetter();
withoutGetterSetter.age = -5;
WithGetterSetter withGetterSetter = new WithGetterSetter();
withGetterSetter.setAge(-5);
}
}
Get and Set methods are preferable to "public" variables because they insulate the users of a class from internal changes.
Supposing you have a variable "StockQty" and you made it public because that seemed like the easiest thing to do.
Later on you get a user requirement to track the history of stock over time. You now need to implement a SetStockQty() method so you can save the old quantity somewhere before setting the new quantity.
Now all the users of your class have to change there code, re-document and re-test.
If you had SetStockQty() method to begin with only you would need to change and test your code.
The second reason is you can have Getters without Setters effectivly making the variable "read only".
Traditionally, they are justified in terms of encapsulation. By providing moderated access to read and write the fields of a class, we supposedly reduce coupling.
In simpler language: by controlling the ways in which other classes can read and change our data, we reduce the ways in which our class's data can change. This means that the connections between classes are reduced, which reduces complexity.
However, the same logic says that getters and setters should generally be avoided unless there's an actual need for them, and there very seldom is such a need. For the most part, a class should "tend to its own knitting" - if there's a calculation to be done on this class's data, it should do it. If a value should be changed, it should do the changing.
For example, consider an object in space. It has a location specified as (x,y,z). We could possibly allow other classes to just set those arbitrarily - this would be horrible, obviously, but it's not obvious that a setter for these would be any better. What you really want is a constructor to set an initial position, and then methods to influence that position - for example, to register an impact or an acceleration. Then you're doing OO programming.
One word, Encapsulation.setters also allow you to control how values are entered into your program. Many new programmers like myself are often confused by this concept. I strongly advice you read this SO question
Being objective: it's all about best pratices!!!
1) IF necessary, expose your attributes with get methods.
2) IF necessary, allow attribute modification (state modification) using set methods;
Have both public get and set methods without treatment is the same as have the attributes public.

Object in Object Array doesn't want to store my data

fairly new to this language. Long time lurker, first time question asker.
In my program, I load a bunch of strings from a text file and then pass all of that information inside of a String array to a program that takes the data point by point (it comes in a reliable pattern) and assigns it to variables inside a class.
I use this loop to create the objects.
Gladiator[] gladiator = new Gladiator[(match.contestants)];
for ( int a = 0; a < match.contestants; a++) {
gladiator[a] = new Gladiator();
gladiator[a].populategladiators(parsedInfo,a);
}
Gladiator class full of public final variables which are defined in the method populategladiators. The syntax is as follows:
this.name = parsedInfo[0+mod][0];
this.culture = parsedInfo[1+mod][0];
this.background = parsedInfo[2+mod][0];
etc.
At the moment, I only load two gladiators and it seems like maybe both are being set at once with both pass throughs? Anyone have any thoughts on this?
Also, in another method in class Gladiator, should I be able to call this.name and be okay to get data about the object I specified when calling the method?
Edit: Trying to make the code look right. Giving up since there isn't much.
2nd Edit: Example of variable declaration in gladiator class:
public static String name;
public static String culture;
public static String background;
I had my variables set as static, thus it wasn't allowing me to set individual variables for the objects. I just didn't understand what the static keyword meant.

Categories