• Post Reply Bookmark Topic Watch Topic
  • New Topic

A Tale of Two Classes (Efficiency in Coding)  RSS feed

 
Shaman Dasuta
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Purpose 1: Enter Name and Age and have program print Name is Age. (NameIsAge
Purpose 2: Enter two numbers and take average and display it.(NumberData)

Using a launcher and making the two programs "proper objects," I set out to do this. For some reason the code for purpose 2 looks drastically different.

Note: for Purpose 1 I followed another coder's advice and whatever Eclipse told me to do. For purpose 2 I knew what I was doing.
Also the reason for comparison is that I feel the programs are similar in purpose (Get user entry and display with a message).


My questions are after the code.

NameIsAge


NameIsAge Launcher



NumberData


NumberDataLauncher.java



Questions:

1) What is the point of the "Getter" and "Setter" in NameIsAge? I seem to be able to work with data variables without that in NumberData.

2) Why do I have so many variables declared in multiple places for NameIsAge, but just once in NumberData?

3) How can I change the entry method to the parenthesis?

For both programs instead of user entry can I just run it like this:
chicken.run(1, 3)

or in Name is Age:
blah.run(Jean, 32)

4) Lastly in NumberData I account for only 2 numbers entered into the array

How can I include more entries? Just declare more variables? Any less cumbersome way? What if user wants to enter 100 numbers?

Thanks for your time in advance! I know these are slightly bizarre in that they both work why question it? - I just want to know so I can write the "correct" way if there is one in Java.
 
Campbell Ritchie
Marshal
Posts: 56536
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Shaman Dasuta wrote: . . .
. . . they both work why question it? . . .
Do they both work now?
 
Knute Snortum
Sheriff
Posts: 4276
127
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What is the point of the "Getter" and "Setter" in NameIsAge? I seem to be able to work with data variables without that in NumberData.


In general, you don't want other people (the users of your class) to manipulate the internal fields. You might think that if you have both a getter and a setter that this is the same as using the field directly, but you can do things like make defensive copies with a getter and you can validate data with a setter. Also, it's a Java Beans convention.
 
Knute Snortum
Sheriff
Posts: 4276
127
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
How can I change the entry method to the parenthesis?


Do you know about parameters in constructors and methods? Try starting with this and see if you can complete the code:

 
Knute Snortum
Sheriff
Posts: 4276
127
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Lastly in NumberData I account for only 2 numbers entered into the array

How can I include more entries? Just declare more variables? Any less cumbersome way? What if user wants to enter 100 numbers?


You could ask for an array of numbers to add, but there is a better way, in my opinion: use variable parameters. Again, I'll start you off:


 
Shaman Dasuta
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:Do they both work now?


Yes with halb it works and I even added a System.out line that prints Campbell is 97.

Knute Snortum wrote: You could ask for an array of numbers to add, but there is a better way, in my opinion: use variable parameters. Again, I'll start you off:

public class AddManyNumbers {

private int total = 0;

public AddManyNumbers(int first, int... rest) {
// what goes here?
}
}|


I wanted to avoid declaring each one (int first, int second, int third, ...etc.)
Unless this is unavoidable/needs to happen once in the code.

Also about parameters in constructors and methods - I am aware of this. I guess just nervous to try them. I'll just go for it.

Anybody have an answer to this: 2) Why do I have so many variables declared in multiple places for NameIsAge, but just once in NumberData?

Thanks a lot everyone!
 
Knute Snortum
Sheriff
Posts: 4276
127
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Shaman Dasuta wrote:I wanted to avoid declaring each one (int first, int second, int third, ...etc.)
Unless this is unavoidable/needs to happen once in the code.


The ellipsis (...) in the code is literal. There actually are only two parameters, first and rest.

Also about parameters in constructors and methods - I am aware of this. I guess just nervous to try them. I'll just go for it.


They're used all the time so yes, go for it and get used to them!

Anybody have an answer to this: 2) Why do I have so many variables declared in multiple places for NameIsAge, but just once in NumberData?


Terseness is not always correctness. It doesn't seem like a big deal to expose your fields when you're writing little programs that only you use, but when you start writing bigger programs that a lot of people use, you can't "take back" an exposed field. So if you wanted to add a defensive copy or an input validation, it's too late!
 
Knute Snortum
Sheriff
Posts: 4276
127
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Shaman Dasuta wrote:
Campbell Ritchie wrote:Do they both work now?


Yes with halb it works and I even added a System.out line that prints Campbell is 97.


But "Campbell" and 97 are the values for halb, not blah! The way NameIsAge is written, all objects will have the same name and age! Can you see what's wrong?
 
Campbell Ritchie
Marshal
Posts: 56536
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Shaman Dasuta wrote: . . .
Yes with halb it works and I even added a System.out line that prints Campbell is 97.
. . .
Did you read my code? I didn't print halb; I printed blah. I used your code with only those three lines added. And I still got
Campbell is 97
 
Shaman Dasuta
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:
Shaman Dasuta wrote: . . .
Yes with halb it works and I even added a System.out line that prints Campbell is 97.
. . .
Did you read my code? I didn't print halb; I printed blah. I used your code with only those three lines added. And I still got
Campbell is 97


EGADS! This actually sucks. See Below:



They both print this:

Enter your name:
kh
Enter your age:
89
Campbell is 97.
Campbell is 97.


This makes this program useless since now it matters when and where you print System.out.

I thought by creating these two objects I am creating two DIFFERENT instances of userName and userAge?

Knute

I'm looking into your code. Not sure of how to add an array. I imagine a for loop with Scanner input?
 
Campbell Ritchie
Marshal
Posts: 56536
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Forget about arrays and Scanners. Start by looking at the code which I took 1 minute to break. Note that I broke the two fields, and it took me only a few seconds to see what was wrong. Look at those fields and see what you have done wrong. Then you can have a useful lesson and you won't forget it in a hurry

Then we can work out what you did wrong in the constructor.
 
Shaman Dasuta
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:Forget about arrays and Scanners. Start by looking at the code which I took 1 minute to break. Note that I broke the two fields, and it took me only a few seconds to see what was wrong. Look at those fields and see what you have done wrong. Then you can have a useful lesson and you won't forget it in a hurry

Then we can work out what you did wrong in the constructor.


So I understand with the constructor I should assign like this:
this.userName = userName;
this.userAge = userAge;

But I am lost on the variables. I cut out the static because as I read once the variables are initialized as static class variables they dont change. Thus I should just erase the word.

Problem with this is now that it gives this error message in launcher:

Cannot make a static reference to the non-static field NameIsAge.userName
 
Campbell Ritchie
Marshal
Posts: 56536
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That is one mistake you have found. (Well done.) The way you had it at first, you were assigning the parameter from the field (which at that time points to null). Another mistake is to write
name = name;
in the constructor, which simply reassigns the variable (usually a parameter) to the same value it had all along.

I have a little rule of thumb. If you don't have a good explanation for a particular keyword, it is a serious mistake. That keyword appears in the declarations of the fields.
 
Campbell Ritchie
Marshal
Posts: 56536
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
By the way: mark all variable fields private.
 
Shaman Dasuta
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok so I marked the variable fields private. Which means to access them I need a getter or setter. Also I moved all actions to the object.run commands.

NameIsAge.java


NameIsAgeLauncher



My last two questions are this:

After I create a new objects blah and halb - and I tell them to run with this:

Why put args? What does that mean?

Lastly in the NameIsAge java file - why do I have multiple this.variable = variable?

If I take out the this.userName = userName - it returns an error.

Any other comments?
 
Campbell Ritchie
Marshal
Posts: 56536
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Maybe you should have called the run method displayDetails. You would be better to give that class a toString() method. Then you can write
System.out.println(blah);

The reason for writing this. is that you have fields and local variables (well, parameters, but they behave similarly to local variables) with the same name. This may cause confusion, but the stylistic advantage of exposing a well‑chosen name should outweigh that. You have gone to a lot of trouble choosing the best name for your fields; if you use the same name for the parameters, then the javadoc tool will display that best possible name for the whole world to see
There is a problem however. Your local variable/parameter shadows(←Java® Language Specification link: may be difficult to read.) the field, so inside the setName method, plain simple name means the local variable. That is why the older version
name = this.name;
set the parameter rather than the field. You have to disambiguate the two versions of name, which you do by writing this. before it.

Be grateful for small mercies. The following isn't valid Java® code, but is valid CYou can put some more code in that and not have the faintest idea which i you are dealing with
 
Campbell Ritchie
Marshal
Posts: 56536
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
About args: look in the Java® Tutorials. I think you will find args is the command‑line arguments, which you will find out about via that link.
You haven't demonstrated it works until you have two different objects. So you will have to repeat the process. But before you do you should search my posts for “Beatles” and when you find that you know you have to call stdIn.nextLine twice, discarding the first input.
 
Knute Snortum
Sheriff
Posts: 4276
127
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Lastly in the NameIsAge java file - why do I have multiple this.variable = variable? If I take out the this.userName = userName - it returns an error.


The NameIsAge class is now a very typical Java Bean type class. It's strengths have been tested over the years. You should get used to this style.

this.var = var is an idiom you will see a lot in setters and constructors.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!