Object Construction - java

I know there is an easy solution to this problem but it's driving me crazy. Why is there an error when I want to print the new Rectangle? any help appreciated!
public class Rectangle {
public Rectangle(int x, int y, int width, int length) {
x = 5;
y = 10;
width = 20;
length = 30;
Rectangle box = new Rectangle(5, 10, 20, 30);
System.out.println(new Rectangle());
}
}

There are several problems with your code. First, you may not want to instantiate a Rectangle in the constructor of Rectangle as will lead to infinite recursion. The second problem is that you are calling a constructor that does not exist.
When you write:
new Rectangle()
the Java compiler will look for a constructor in the Rectangle class that accepts no arguments. But your code does not have such a constructor. You can add one like this:
public Rectangle(){
//Your code here to instantiate a default rectangle
}
Usually a constructor is used to set the values of the instance variables in a class rather than to execute code the way you have written it. You can move those lines that are creating rectangles into a main method to test the code.

Here is some code that does what I think you want it to:
public class Rectangle
{
int x, y, width, length; //declares the class's fields
public Rectangle(int x, int y, int width, int length)
{
this.x = x; //initializes the field x to the value of the local variable x
this.y = y; //initializes the field y to the value of the local variable y
this.width = width; //initializes the field width to the value of the local variable width
this.length = length; //initializes the field length to the value of the local variable length
System.out.println(this); //prints this object. should look similar to "Rectangle#1246889"
}
}
Please take a basic java tutorial (e.g. Providing Constructors for Your Classes), it will make your life easier.

You are calling a non-parameterized/default constructor from a parameterized constructor. The JVM in this case unable to create the default constructor. Hence in this case you need to include non-parameterized constructor explicitly into your class.
public class Rectangle {
public Rectangle(int x, int y, int width, int length) {
x = 5;
y = 10;
width = 20;
length = 30;
Rectangle box = new Rectangle(5, 10, 20, 30);
System.out.println(new Rectangle());
}
public Rectangle(){}
}
This will be error free.

First, the code (as you have provided it) can not possibly compile: you haven't declared x, y, width and height as member variables (fields) of your Rectangle. E.g.
// I'm assuming you want these private and final (I would)
private final int x, y, width, height;
Alternative, for a quick hack:
int x, y, width, height;
You are also trying to call a 0-argument constructor on your println line. Your class doesn't have a 0-argument constructor; it has a 4-argument constructor. I suspect (as noted above) you really want to print this.
But that wouldn't help much, on its own, unless you add an appropriate toString method to your class. E.g.:
public String toString() {
StringBuilder sb = new StringBuilder("Rectangle: ");
sb.append("x=").append(x);
sb.append(", y=").append(y);
sb.append(", width=").append(width);
sb.append(", height=").append(height);
return sb.toString();
}
You might want to think about implementing equals() and hashCode() too, if you choose to make this class immutable (I would). You can ixquick* or duckduckgo* this - there are plenty of explanations around.
[*] They are search engines: I don't use google.

Related

Can I accessing variables which is declare in say class A from say class B in Java [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I am a newbie in Java. I have done a sample program that is finding the area of a rectangle. The code is below.
package rectangle;
public class Rectangle {
int length, width;
int rectArea() {
int area = length * width;
return (area);
}
}
class RectArea {
public static void main(String[] args) {
int area1;
Rectangle rect1 = new Rectangle();
rect.length = 14;
rect.width = 13;
area1 = rect.rectArea();
System.out.println("Area1=" + area1);
}
}
In the above code length and width are variables which declare in class Rectangle. Now area is also a variable which holds the data length * width and this areavariable is also declared in class Rectangle
We can access length and width variables from another class named RectArea by using the dot operator. But why can't we access area variable which is declared in Rectangle class from the RectArea class (using dot operator) directly to evaluate the value of Rectangle?
That is, why we can't use the below code to evaluate the value of a newly created object rect1 from RectArea class.
area1 = rect1.area;
System.out.println("Area1="+ area1);
Or why can't we access the area variable which is declared in Rectangle class from RectArea class using the above code?
area is not the class level variable. Its a local variable in rectArea method, thus, it will not be visible outside the method and won't be accessible via dot operator like class variables
area is not class variable, it is inside method and you can not access method variable as these are local and visible to method only.
There are local variables and instance (class) variables. The class variables are like length and width and they can be used within the whole class.
But with local variables they can only be used within the method/block of code where you have declared them. In this case area is declared in the method and is only available in the method.
Once the code jumps out of the method (return ) area no longer exists.
I have fixed the code below so that it does work:
int length, width, area;
void getData(int x, int y)
{
length=x;
width=y;
}
int rectArea()
{
area=length*width;
return area;
}
}
class RectArea{
public static void main(String[] args) {
int area1, area2;
Rectangle rect1 =new Rectangle();
Rectangle rect2 =new Rectangle();
rect1.length=14;
rect1.width=13;
area1=rect1.length*rect1.width;
rect2.getData(13,14);
area2=rect2.rectArea();
System.out.println("Area1="+ area1);
System.out.println("Area1="+ area2);
System.out.println("Area1="+ rect2.area);
}
}
area is a local variable of the method rectArea. It is not accessible outside the class or even inside the class, except for the same method.
If you want area to be accessible outside, why don't you try something like this:
public class Rectangle {
int length, width, area;
void getData(int x, int y) {
length = x;
width = y;
area = length * width;
}
}

Drivers for Classes in Java “Rectangle"

I’ve never used a separate file for a driver in Java. I’m used to just using a main method. I’ve used separate files in Python but Java is new. Below is my code for each class (“Rectangle” and “Driver”), each from separate files.
Update with the methods changed to static: Don’t pay attention to the change in class names or formatting…I’m just tweaking so it will work with MyProgrammingLab. I still have to add in parameters for length and width being between 0.0 and 20.0 only (easy if-else statements).
import java.util.Scanner;
public class Driver{
public static void main(String[] args) {
Scanner input = new Scanner( System.in);
System.out.print("Enter length of rectangle:");
double length = input.nextDouble();
System.out.print("Enter width of rectangle:");
double width = input.nextDouble();
Rectangle Perimeter = new Rectangle(length, width);
Perimeter.getPerimeter();
Rectangle Area = new Rectangle(length, width);
Area.getArea();
System.out.printf("Area: %.1f, Perimeter: %.1f",Rectangle.getArea(),Rectangle.getPerimeter());
}
}
final class Rectangle {
private static double mLength;
private static double mWidth;
public Rectangle(double length, double width){
mLength = length;
mWidth = width;
}
public double getLength(){
return mLength;
}
public double getWidth(){
return mWidth;
}
public static double getArea(){
double area = mWidth*mLength;
return area;
}
public static double getPerimeter(){
double perimeter = (mWidth*2)+(mLength*2);
return perimeter;
}
}
It makes more sense to create a Rectangle object with it's length & width, so use your overloaded Rectangle constructor by passing the length and width arguments (entered by user) as shown below:
Rectangle Perimeter = new Rectangle(length, width);
the constructor Rectangle() is undefined. Can anyone help?
The important point is that when you have an overloaded constructor like in your Rectangle class (where there are no default i.e., no argument constructors written), you can't create an object using new Rectangle();, this is because compiler doesn't add the default constrcutor automatically for you. I suggest look here for more details on this.
Also, if you wanted to print the Rectangle object with length & width details, you need to override toString() method from java.lang.Object method as shown below:
public class Rectangle {
private double mLength;
private double mWidth;
//add your code here as is
#Override
public String toString() {
return "Rectangle [mLength=" + mLength + ", mWidth=" + mWidth + "]";
}
}
The default constructor is provided by compiler if there are no constructor written explicitly.
But if you explicitly write any constructor in the class, then whenever you call a constructor, be it no-argument or with arguments, it will always look for explicitly defined constructor in class.
And, this is logically correct since, if you want to block creation of objects without any data in it, adding a constructor with argiment is the way to go.
So either explicitly write a no argument constructor in Rectangle and use setter to set its attributs, or just use the argument constructor in your method.
Add to Rectangle.class an empty constructor :
public Rectangle() {
}
Or Use constructor declared with parameters in your method
Rectangle rectangle = new Rectangle(length, width);
In your case you are using the rectangle object wrong.
I think what you looking to do is this :
Rectangle rectangle = new Rectangle(length , width );
System.out.printf("Area: %.1f, Perimeter: %.1f",rectangle.getArea() ,rectangle.getPerimeter());

In Java, can the number of variables passed in value be less than the number of variables in the object's class?

This is an excerpt from Oracle's Java tutorial website. It doesn't show the actual .java files, but I'm guessing "Rectangle" is a class. But if you note, the parameters passed down (by value?) for rectOne and rectTwo are different. (one has the origin variable while two does not)
If the object has certain number of parameters, can the actual number of passed down values be less than that? I'm assuming it can't be more by default.
Also, I searched for answers but cannot find.
// Declare and create a point object and two rectangle objects.
Point originOne = new Point(23, 94);
Rectangle rectOne = new Rectangle(originOne, 100, 200);
Rectangle rectTwo = new Rectangle(50, 100);
An object doesn't have parameters - a method or a constructor does. In this case, basically there are two overloaded constructors. For example:
public Rectangle(Point origin, int width, int height)
{
this.origin = origin;
this.width = width;
this.height = height;
}
public Rectangle(int width, int height)
{
this(Point.ZERO, width, height);
}
The only time in which the number of argument expressions for a single overload can vary is with varargs:
public void foo(String... bar)
{
...
}
foo("x"); // Equivalent to foo(new String[] { "x" })
foo("x", "y"); // Equivalent to foo(new String[] { "x", "y" })
foo("x", "y", "z"); // Equivalent to foo(new String[] { "x", "y", "z" })
It's an exercise from the Classes topic. I read it too. You can create your own classes as the tutorials showed. Here you have 2 constructors for the class Rectangle1Class with different signatures. One accepts three parameters and the other only two. Try it and it will work. You have to create your class and methods to make it work. For example:
public Rectangle1Class(PointClass cOrigin, int cWidth, int cHeight){
origin = cOrigin;
width = cWidth;
height = cHeight;
}
public Rectangle1Class(int cWidth, int cHeight){
width = cWidth;
height = cHeight;
}
Rectangle is a class and it has 2 constructors.
One constructor takes in 3 parameters and the other takes 2.
While initializing objects you would have to make sure that you pass the required number of parameters as present in the constructors of the class.

Simplifying Java method with variable amount of arguments

Working in java, I was wanting to simplify a draw function (polygon creator) that I am working with. Typically, when you create a polygon, you do this:
Polygon mypoly = new Polygon();
mypoly.addPoint(x1, y1);
mypoly.addPoint(x2, y2);
mypoly.addPoint(x3, y3);
Draw.fillPolygon(g, mypoly, Color.blue);
I would like to use an image mapper to automatically give me the coordinates, so I could just copy paste them into my own function.
myCommand(x1, y1, x2, y2, x3, y3);
Each of these would go into the polygon command on the top. The problem that I am facing though is that when mypoly is created, how would it know how many points to add and where to put them?
I am trying to get myCommand to automatically add points as I add arguments, and each point to correspond with the x,y of the original polygon creation method.
Sounds like you need to make use of the builder pattern. In pseudocode:
PolygonBuilder pb = new PolygonBuilder();
pb.addPoint(1,1);
pb.addPoint(1,2);
// etc...
Polygon p = pb.newPolygon();
so the idea is that you provide the builder with a set of points, and it'll generate you the appropriate polygon. Builders are often designed with a fluent interface. Note that the builder can act like a factory and return you appropriate subclasses of Polygon (square, triangle, pentagle etc. if you so wish).
Note that you could instead provide a method that takes a variable number of arguments, using the Java varargs mechanism. e.g.
public void addPoints(Integer... args) {
// and iterate here
}
You may wish to create a Point object to define an x/y coordinate together. Otherwise the above will have to check for an even number of arguments, and those arguments won't be tied together.
You can use varargs and create the polygon dynamically by using the constructor that gets arrays of xs and ys
(Code not tested)
public Polygon createPolygon(int... points) {
if (0 != points.length % 2) {
throw new IllegalArgumentException("Must have even number of points");
}
int numOfPoints = points.length / 2;
int xs = new int[numOfPoints];
int ys = new int[numOfPoints];
for (int i=0; i < numOfPoints;i++) {
xs[i] = points[i*2];
yx[i] = points[i*2 + 1];
}
return new Polygon(xs, ys, numOfPOints);
}
Then you can invoke the method with any number of points
Polygon p = createPolygon(x1,y1,x2,y2,x3,y3);
To extend Brian Agnew's answer, it might also be worth adding a Point class which the addPoints method could take in. It could make it slightly easier to add/remove points from your polygon.
public final class Point<X,Y>{
private final X x;
private final Y y;
public Point(X x, Y y){
this.x=x;
this.y=y;
}
public X getX(){return x;}
public Y getY(){return y;}
}
Then you could have a:
public void addPoints(Point<Integer,Integer>... points){
for(Point<Integer,Integer> point:points)
//your logic
}
I think you could use a method that received a varargs (...)
You need a wrapper for each point:
class Point {
int x;
int y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
}
The method could be:
myCommand(Point ... points)
For call
myCommand(new Point(0,0), new Point(1,1), new Point(0,1));
And for draw:
Polygon mypoly = new Polygon();
for(Point p : points)
mypoly.addPoint(p.x,p.y);
Draw.fillPolygon(g,mypoly,Color.blue);

Why is the output this? (Java)

This is an instance method from a Rectangle class where we modify the x and y coordinates of the rectangle and its width and height
public void modify(int newX, int y, int width, int h) {
int x = newX;
this.y = y;
width = width;
this.height = height;
}
Rectangle r3 = new Rectangle(0, 0, 10, 10);
r3.modify(5, 5, 50, 50);
System.out.print(r3.getX() + " " + r3.getY() + " ");
System.out.println(r3.getWidth() + " " + r3.getHeight());
I have this code and I know that the output is 0 5 10 10 but i'm not entirely sure why. can anyone explain why?
public void modify(int newX, int y, int width, int h) {
int x = newX; // the value isn't saved to the class members
this.y = y; // this is saved, hence you see the change in the y value
width = width; // meaningless, the variable is overwritten with it's own value
this.height = height; // who is height? the function receives h
}
You have created a new object of type "int" for X within the modify method. This means that it only exists within that method since you're not passing it by reference. So, the newX value is only 5 within the modify method, but does not exist as '5' outside of it. this.y works fine because you've called that specific instance of the object and modified it's value. Therefore, it's retained outside the method. 'width = width' doesn't work because you're simply assigning 50=50 (since you've inputted 50 as the width). 'this.height = h' would be fine, but you've said 'this.height = height'. But, from the code you've given, 'height' doesn't exist.
y is the only instance variable that is actually modified in the modify method. The other the arguments passed in have no net effect on the state of the object.
Actually, the code shouldn't compile. height isn't defined in your method call. Unless this is another property that you didn't include in your code snippet.
int x = newX creates a new int named x that you then do nothing with. That's why r3.getX() returns 0, since you never modified it.
this.y = y changes the value of the field y within the Rectangle class. This is why this change is shown in your output as 5.
width = width changes the method parameter named width to itself. It doesn't change the value, but it also doesn't set the field width within Rectangle. No change shown, original value of 10 prints.
If height is a field elsewhere, then it makes sense that r3.getHeight() wouldn't update the field, since the parameter in the method call is for h, not height. If not, then I don't know how the code compiles since height isn't mentioned anywhere.
The "int x = newX" line creates a variable "x" on the stack that exists only for the duration of the current method call.
"this.x" would refer to the "x" created by the classes constructor. Which is probably what "getX()" returns.
This code shows the difference between the function stack variable and object variable. For function modify, the four passing variables are on the stack. The line declares a stack variable x and set its value as newX. The second line uses the object variable this.y and set to passing variable y. The third line is to assign the width to its self on stack. The fourth line uses the object variable height and assign to its self. Once the program goes out of the scope of function modify, all its stack variables' value are whacked. So the result is 0 5 10 10 because only the second line which is not stack variable this.y retains its value after calling function modify.
I would venture to say your issue is in how you are assigning the new values of x, y, width and height to your rectangle object.
Assuming that your modify method is in the rectangle class your code currently looks like this (I added comments on the mistakes:
public void modify(int newX, int y, int width, int h) {
int x = newX; //you are declaring a new x here...not assigning newX to rectangle's x
this.y = y; //this is correct
width = width; //here you're just assigning the parameter width its current value
this.height = height; //here you are assigning the rectangles height value to itself
}
I would HIGHLY advise finding a naming convention and sticking with it as it would help tremendously here.
Try something like this:
public void modify(int x, int y, int w, int h) { //changed names of parameters
this.x = x; //removed the int type declaration and used this. prefix
this.y = y; //changed nothing
this.width = w; //adjusted for renamed parameter, used this. prefix
this.height = h; // adjusted for renamed parameter, again used this. prefix
}
As you can see, sticking to a convention makes the code less confusing and easier to read. This also allows you to see your mistakes more easily as they will usually stick out from your convention like a sore thumb. Don't worry it comes with practice.

Categories

Resources