In my Java basic class my teacher told me to comment any arbitrary choice that I make when I write a default constructor for a class. (She told us that we must create a default constructor for every class that we design) So for example, I'm writing a class named RoomDimension, and I created a default constructor as follows:
public class RoomDimension {
//Fields
private double length; //Length of a carpet
private double width; //Width of a carpet
/**
*
*/
public RoomDimension(){
length = 0.0;
width = 0.0;
}
I'm using here 0.0 as my flag to indicate the user has entered nothing or an invalid input. Should I then comment the fact that 0.0 is used as an indication of an invalid input in the documentation comment(/**/)? I know that if I were to use -1 as my flag (or an initialization of a field in default constructor), I would definitely comment that -1 indicates an invalid input because I made that decision arbitrarily. I'm asking whether 0 has to be commented or not because I don't know if 0 is an arbitrary choice or not. Would you, as a programmer, bother to indicate that? Or, is it okay if I just assume that the user knows it without telling them?
As to whether zero should be commented, I think it would be best to indicate it is a flag in order to remind yourself in the future, or any other programmer that looks at your code.
As for using zero as a flag, I think it would be better practice to throw an exception when length and height are less than or equal to zero. It would be easier to read in the future, and more efficient to handle when a user does enter a non-positive number.
She told us that we must create a default constructor for every class
that we design
And I told for my teacher: Who don't know is teaching, who know is doing!
If you don't create a default constructor, the compiler will do it, did you know? - how about your teacher?
Many tools, which generates, transform data will cry, nags, crash if they don't find a COMPILED "default constructor". But they will completely ignore the comments.
So back to your class:
public class RoomDimension {
static {
System.out.println("I an a static initializer, If the classloader will touch your class, I will be called first! ex. RoomDimension.anyStaticmethod() or before new RoomDimension()");
}
{
System.out.println("I am instance initializer. whenever you call any constructor, I will run before the constructor body, try me with: new RoomDimension()");
}
//Fields
private double length; //Length of a carpet
private double width; //Width of a carpet
public RoomDimension() {
length = 0.0;
width = 0.0;
}
}
By the way in your code:
public RoomDimension() {
length = 0.0;
width = 0.0;
}
it is completely useless, because before constructor, it will be an initialisation and that will do exactly the same, because you have declared as properties and they will be initialize, before constructor:
private double length; //Length of a carpet
private double width; //Width of a carpet
If you want to know it is initialized or not, use Double instead of double and check for null value.
Ex:
private Double length; //Length of a carpet
private Double width; //Width of a carpet
I would set the values of those to be nullable.
public class RoomDimension
{
private double? length;
private double? width;
}
public RoomDimension()
{
}
What this does for you is allow the values of length and width to take the value of null. So when you call the default constructor, they are automatically set to null.
This will help you start thinking in terms of objects, because when you have objects that contain other objects you cant set all the contained objects to 0.0, you just create a null object. Also when you perform actions on that object you just check if its null beforehand this helps to avoid null reference exceptions.
Related
I am trying to build a Java program based on this UML:
UML of Polygon Class
But I ran into a few hiccups along the way. This is my basic code:
import java.util.Scanner;
public class Polygon {
private int[] side;
private double perimeter;
public double addSide(double length[]) {
int i = 0;
double perimeter = 0;
while(length[i] > 0){
perimeter += (double)length[i];
i++;
}
return perimeter;
}
public int[] getSides() {return side;}
public double getPerimeter() {return perimeter;}
public static void main(String[] args) {
Polygon polygon=new Polygon();
polygon.side = new int[99];
int i=0;
do{
System.out.print("Side length(0 when done): ");
Scanner in = new Scanner(System.in);
polygon.side[i] = in.nextInt();
i++;
}while(polygon.side[i]>0);
//polygon.perimeter = addSide((double)polygon.side);
System.out.println("Perimeter of " + i + "-sided polygon: " + polygon.getPerimeter());
}
}
There's a couple of issues.
I got it to compile but when it accepts the first side[0], it immediately stops and gives me the perimeter. Exiting the loop eventhough the conditions haven't been met for it to so. So there's an issue with my while-loop. I want it to keep accepting values into the side[] array until a non-positive value is entered.
Also the UML requires I use double parameter-type for the addSide method. I tried to cast it in the argument and tried a couple of other different things with no success. How would one transition an int-array into a double-array for the perimeter calucalation which has to be double as per the requirements.
I wouldn't surprised if I made other issues since I'm new to Java so feel free to point them out to me or if you have a better way to go about this, I would love to learn your thinking.
Any advice is appreciated!
There are a number of issues with your code.
First, differences from the UML specification:
You haven't used the given signature for addSide. The UML says that it takes a single double parameter, and returns nothing, i.e. void in Java. You are passing an array of double and returning a double.
You are directly accessing sides in your main method. Java allows you to do this, because your main method is part of the Polygon class, but the UML shows that the field is private. What does direct manipulation of sides do to the validity of the value in perimeter?
The UML shows the class having a field sides of type int. Your field sides is of type int[].
Similarly you haven't used the given signature for getSides, which should probably have been named getNumberOfSides.
Your code has quite a few other issues, but I think you should fix the issues above first.
A futher hint: The only things that the Polygon class can do is to tell you how many sides it has and what its total perimeter is. It does not care about the details of individual sides.
(Off topic, it is strange to include main in the UML description of Polygon)
So I am working on an incremental game at the moment. In case you don't know what this is a short explanation. You click a button to get some kind of money (in my case gold). With enough money you can buy stuff that makes you money without even clicking. With more money you can get better upgrades which makes you even more money and so on.
Now to my problem; I created a class called Upgrade which you can see here:
public class Upgrade {
double baseCost;
double baseIncome;
int count =0;
double cost = baseCost*Math.pow(1.07,count);
double goldPerSecond = baseIncome; //TODO find usefull formula!
public Upgrade(double baseC, double baseIn){
baseCost = baseC;
baseIncome = baseIn;
}
}
The variables should explain themselves.
Now I created some Upgrades via the constructor:
Upgrade waitress = new Upgrade(50 ,2); //Constructor for Waitress
Upgrade seats = new Upgrade(100, 5); //Constructor for More-Seats
Upgrade decoration = new Upgrade(500, 20); //Constructor for Decoration
Upgrade bartender = new Upgrade (1000, 50); //Constructor for Bartender
To buy upgrades I have written the method buyUpgrade which is bound to buttons referring to the upgrades listed above.
public void buyUpgrade(Upgrade U) {
if (goldCount >= U.cost) {
goldCount = goldCount - U.cost;
clickGoldPerSecond++;
U.count++;
} else {
error.setText(getResources().getString(R.string.no_gold));
}
}
And here comes the problem. As the game starts you have 0 gold. That 0 is stored in the variable goldCount. But even though goldCount is I can buy every Upgrade in unlimited amounts. I just cant figure out the problem. Probably it is really simple and afterwards I realize how stupid I was but I just cant figure it out.
Every help is appreciated. Thank you!
The problem is that
double baseCost;
double baseIncome;
int count =0;
double cost = baseCost*Math.pow(1.07,count);
baseCost being the member variable of the class, is intialized to 0.0
SO "cost" set to 0.0 and it never changed after that.
You should move the cost calculation in the constructor.
public Upgrade(double baseC, double baseIn){
baseCost = baseC;
baseIncome = baseIn;
cost = baseCost*Math.pow(1.07,count);
}
public class Upgrade
{
double baseCost;
double baseIncome;
int count =0;
double cost ;
double goldPerSecond;
public Upgrade(double baseC, double baseIn)
{
baseCost = baseC;
cost = baseCost * Math.Pow(1.07,count);
baseIncome = baseIn;
}
}
Your Upgrade class should be similar to what I have created here. If there is a non static filed in the class and you are assigning value to that variable in the way you were doing it will not work.
In your case you also cannot use the static variable as the variable baseCost is passed as constructor parameter and will not be available until you create an instance of upgrade class.
If Condition if(goldCount >= U.cost){} Here the cost will have value of zero only as it would not get updated.
Here is your problem:
int count =0;
double cost = baseCost*Math.pow(1.07,count); // cost is set and will not be updated
Pls note that you update baseCost in your constructor, but before that the default value 0.0 is being used for baseCost * Math.pow(...);. But even if you update that, by having it done in the constructor, still you will not see any price going up, because the cost is not being recalculated at all.
Set the initial value in the constructor (or have baseCost always being added to the cost when accessing the cost).
Make a method which adds one to count and then does Math.pow(...) on cost again.
Now for a much better solution: hence, in this case the attribute cost is useless. Change it into a method:
public double getCost() {
return baseCost*Math.pow(1.07,count);
}
call it (change 2x U.cost --> U.getCost()) and your sky will be blue again, no further change needed where ever.
You are missing getter/setter for cost i guess. Therefore it always return 0.0.
I mean try to create an Upgrade object with the constructor, then print out the cost. No matter what you give in the constructor, the cost for the object always print out "0.0".
Write a Temperature class that represents temperatures in degrees in both Celsius and Fahrenheit, using a floating-point number for the temperature and character for the scale: either āCā for Celsius or āFā for Fahrenheit. The class should have
Four constructors:
one for the number of degrees,
one for the scale,
one for both the degrees and the scale, and
a default constructor.
For each of these constructors, assume zero degrees if no value is specified and Celsius if no scale is given."
Hey there I am an amateur java programmer... I have been asked to do the above statement and I am not all that familiar with constructors but I'm open to any knowledge :) obviously I'm not asking for someone to give me an answer to my question but maybe someone can give me some advice on how I get started... here's what I have done so far:
public class TemperatureApparatus {
public class temperature{
private float c;
private float F;
public temperature(){
}
public temperature(){
}
public temperature(){
}
public temperature(){
}
}
public static void main(String[] args) {
}
}
Four constructors: one for the number of degrees, one for the scale,
one for both the degrees and the scale, and a default constructor.
These are your constructor arguments. Arguments are passed into constructors and methods via parameters which are listed within the parentheses of the method.
You've got the format of a constructor correct. It's essentially a method that has the same name of the class and no return type. Now you need to add arguments.
The default constructor has no arguments:
public Temperature() { //Class names should be capitalized!
//Default constructors often do nothing, but you can set default values here if you want
}
Here's a signature for a constructor taking the degrees only:
public Temperature(float degrees) {
//Assign the "degrees" argument to an instance variable here
//You might consider assigning a value to a "scale" variable by default as well
}
This assignment probably wants you to fill in that constructor's body, so assign the given value to a float in the class. Now make constructors for the other desired arguments. Since the assignment wants 'F' or 'C' for the scale, you can safely use char as the argument for that data.
Once you've completed the assignment, you might consider challenging yourself with this: Given that a user could now have a Temperature object with a float degree and a char scale, how might you implement a getTemperature() method?
Oh, and there's no reason for you to nest classes like you are. Put Temperature in a separate class from your class that runs main if you need to make a runnable answer.
Here you go
public class Temperature {
private float temp;
char scale;
//first constructor
/*
*Notice how in this first constructor, I put scale
*as 'C' since there was no char value being passed
*as a parameter (no char scale inside the brackets)
*Now i did get a float temp passed a a parameter so
*I set whatever that temp is to the temp of this class
*also known as this.temp (this refers to THIS class
*/
public Temperature(float temp) {
this.temp = temp;
scale = 'C';
//other way
//this(temp, 'C');
}
//second constructor
/*
*Now this constructor is the exact same case at the
*first one, except this one has the char scale passed.
*Since no temp is passed, I set it to 0 as no value is specified
*/
public Temperature(char scale) {
this.scale = scale;
temp = 0;
//other way
//this(0, scale);
}
//third constructor
/*
*This third one is having both temp and scale being specified
*which means you don't need to put any initial value (0 and Celcius)
*Just set these objects to whatever is being passed by through the
*parameters
*/
public Temperature(float temp, char scale) {
this.temp = temp;
this.scale = scale;
}
//fourth constructor
/*
*This last one has no parameters through so
*you can just set both the scale and temp to
*0 and 'C' respectively.
*/
public Temperature() {
temp = 0;
scale = 'C';
//other way
//this(0, 'C');
}
}
Sorry if this is a bit vague. I am new to learning Java.
In my program I have two classes and one of the classes is for user input. The other class calculates that user input and then returns the calculations to the other class. In my calculations class I'm pretty sure I'm making myself work harder and than I should be. I want to have the result of my user input multiplied together but doing that in the calculations class.
Here is my Calculations class.
class Calculations{
double length, width ;
public double floorArea (double length, double width){
return length * width ;
}
public double floorAreaCost (double length, double width) {
return length * width * 6.50 ;
}
public double serviceCharge (double length, double width){
return length * width / 10 + 12.50 ;
}
}
What I want to be able to do is have return length * width = area. Then use that area variable for future reference in the floorAreaCost method and the service charge method. So instead of return length * width * 6.50 I would have area * 6.50
Here's my user input class as well.
import java.util.Scanner;
public class ApartmentUser{
static Scanner input = new Scanner(System.in);
public static void main (String args[]){
int length, width;
System.out.println("Enter the length of the apartment floor: " );
length = input.nextInt();
System.out.println("Enter the width of the apartment floor: " );
width = input.nextInt();
Calculations area = new Calculations();
System.out.println("The area of the apartment floor is: " + area.floorArea(length, width));
Calculations cost = new Calculations();
System.out.println("The cost of the apartment is: " + cost.floorAreaCost(length, width));
Calculations charge = new Calculations();
System.out.println("The service charge cost is: " + charge.serviceCharge (length, width));
}
}
Your methods should call the floorArea method, so for example method shown below
public double floorAreaCost (double length, double width) {
return length * width * 6.50 ;
}
would become
public double floorAreaCost (double length, double width) {
return this.floorArea(length, width) * 6.50 ;
}
That way, the floor area calculation is encapsulated inside one method only and can easily change in one step
First of all you shouldn't make so many Calculations objects, one is enough.
So what you should do is give the Calculations class a constructor like this.
class Calculations{
public double length, width, area;
public Calculations (int length, int width) {
this.length = length;
this.width = width;
area = width * length;
}
Now when you create youre Calculations object:
Calculations floor = new Calculations(int length, int width);
You directly have the area calculated and you can call the methods without having to input the parameters, because they're already saved in the Calculations class.
You can also work with multiple "rooms", because the informations are saved in the Calculations class.
Hope i could help you.
As written, your Calculations class defines a "stateless" object.
Within each function, the function parameters length and width
hide the member variables length and width,
so that the member variables are never use at all.
You should be able to delete the declaration of those member variables
without noticing any change in the behavior of your program.
This is not necessarily a bad thing. Stateless classes can be very useful.
For example, because Calculations is stateless, you do not need to
allocate three different instances to perform your three different functions.
You can call all the functions on the same instance, because none of the
functions can affect the "state" of the object and therefore cannot have
any hidden "side effects" on the results of functions called later.
The return from each function is determined just by the values you
pass to its two parameters.
The program does end up multiplying the same length and width together
three times when once would have been enough.
You will hardly notice the extra computing time in this example
(it is vastly overshadowed by everything else going on here),
but if you had to do millions of these calculations for one user input
you might then notice a difference.
One way to avoid the redundant multiplications
is to return area from the floorArea function,
but pass area (not length and width) as a single parameter to
each of the other functions.
You might also consider creating member variables of Calculations
to store the numbers 6.5, 10, and 12.5 that you use in some of your functions.
That would allow you to give those numbers meaningful, descriptive names.
It would also permit a more sophisticated version of the program to accept
new values of those constants to use in a Calculations object,
allowing the store to change its pricing without rewriting its software.
If you set those values during the construction of a Calculations object
and do not change them in any of the other functions, the object
is still stateless.
Or you could decide to change the class some other way. I see at least three other answers already, each of which proposes a legitimate design of a Calculations class, no two of those designs the same.
First off all when you define fields in your class, it's common practice to define the scope of the variable. So it would look something like this. Which only makes the variable accessible within the class, if you would access it from the main method, you should declare em public. But add your area as a variable.
private double area ;
You need to store your calculated Area on the object, use the keyword this for accessing that variable. When operations on the same object is done, it can be fetched in a similar fashion.
Update your code to this:
public double floorArea (double length, double width){
this.area = length * width;
return this.area;
}
public double serviceCharge (){
return this.area / 10 + 12.50 ;
}
I have the following class:
class Position {
private double x,y;
private int id;
private static int count=0; //counts number of times a Position object has been created
public Position (double initX, double initY) {
x=initX;
y=initY;
id=count;
count++;
}
public Position (Position a) {
id=count;
count++;
x=a.x;
y=a.y;
}
I want to now create a Position object in another of my .java files. How would I do so? Wouldnt I just use Position x=new Position; ? Thats not working. Do I have to import the position class into the files? I tried that too, didnt work. Wouldnt let me import. My files are in the default folder.
Here's where I want to use it. Im not even sure Im reading the instructions correctly. Is this what they want from me? To initialize every element of the array to a new position object?
/**
* Returns an array of num positions. Each position is initialized to a random
* (x,y) position.
* if num is less than zero, just return an empty array of length 0.
*
* #param num
* number of positions to create
* #return array of newly minted Points
*/
public int[] randomPos(int[] a) {
int numPositions=Position.getNumPositionsCreated();
int[] posArr=new int[numPositions];
int x,y;
for (int i=0; i<numPositions;i++)
Position rand = new Position(x,y);
//
You would need to invoke the constructor,
Position x = new Position(2.0,2.0);
Since one of your constructor takes two double's as arguments, I used those as an example.
Or, you could create a new Position object by passing in another Position object,
Position otherX = new Position(new Position(2.0,2.0));
// or combining our above example assuming that x is already instantiated
Position otherX = new Position(x);
Also, just in case you are unsure, there is a difference between instantiation and declaration!
Instantiation:
Position posX = new Position(1.0, 4.0);
Now, posX is an instance of a Position object, because we construct our object by invoking the constructor.
Declaration:
Position posX;
Note that the posX variable is declared to be a Position object, but has not yet been instantiated so posX would have a null reference.
Update:
Without actually do the homework for you, because you will not learn that way. I can tell you that what you have so far, and what is listed in the javadoc above do not agree. Also, given by the way the javadoc is written, it is tough to follow, therefore let me try to clean it up for you and leave you to do the rest,
/* Returns an array of n Positions. Each Position is initialized to a random
* (x,y) position.
* if n is less than zero, just return an empty array of length 0.
*
* #param n
* number of Positions to create
* #return array of newly created Positions
*/
Now we can break down that javadoc, so lets pinpoint what we know.
We are passing an argument, n which indicates how big the Positions array should be.
We need to check to see if n is equal to 0, if so we return an empty Position array.
Each Position object would be instantiated with random x and y values.
We know that we need to return an Position array.
This should get you started, I am sure you can figure out the rest.
Position x = new Position(1.0, 2.0);
For example. The way you have it now is missing method arguments.
Position x = new Position(1d,2d);
You need to pass your constructor arguments. Since you defined 2 constructors on your Position class, you must use one of them. Usually not a bad idea to put a do nothing constructor on your class. like
Postion () {}
or in your case
Position () {
Position.static++;
}
since you are counting. Note you should reference static members statically.
Your constructors take arguments, so you have to provide some.
Position p = new Position(1.0, -2.0);
If you want to create one without arguments, you need to a add a zero-argument constructor.
public Position() {
}
which would then be invoked by doing Position p = new Position() (the parenthesis are required when not passing in arguments)
If you don't define any constructors, java automatically creates an implied zero-arg constructor, but once you define a different constructor, you have to explicitly define a zero-arg constructor to have one.
If both of your classes are in the default package you shouldn't need to import anything.
Java already has a Point class. It may be overkill for you but though I'd mention it.
http://download-llnw.oracle.com/javase/6/docs/api/java/awt/geom/Point2D.html
Don't forget the parentheses and arguments to pass into the constructor when you call new, eg:
Position p = new Position(x, y);
Depending upon where the other class is, you may also need to make Position a public class (it appears you are using the default visibility of package-private).
Also note that x and y must be initialized first,