If a class contains an object as an instance variable, and one of the constructors includes an object of the same type as a parameter, is it best practice to assign the argument to the instance variable, or to create a new object from the argument, and assign THE NEW OBJECT to the instance variable.
Here's an example from an exercise I'm working through:
public class MyCircle {
private MyPoint center; //contains variables int x and int y
private int radius;
//Non-controversial Constructor:
public MyCircle(int x, int y, int radius ) {
//creates new center using a valid MyPoint constructor
this.center = new MyPoint(x, y);
this.radius = radius;
}
//OPTION A
public MyCircle( MyPoint center, int radius ) {
this.center = center;
this.radius = radius;
}
//OPTION B
public MyCircle( MyPoint center, int radius ){
this.center = new MyPoint( center.getX(), center.getY() );
this.radius = radius;
}
}
Initially, I typed option A, but I thought that this could create buggy behavior if this.center referenced an existing object that could be modified indirectly unintentionally. The alternative way of thinking about it, I guess, is that this creates an avenue for creating multiple objects that share a center, and moving a single center would intentionally move all circles that share that center.
Since Java has no pointers (at least not for developers) that option will be discarded and is not the way to go..
Now this:
public MyCircle( MyPoint center, int radius ) {
this.center = center;
this.radius = radius; }
Is in my opinion better, you can just assign the center and don't need to make a risky copy of the class MyPoint... And I say risky because if you want to do that you should at least check the non-null condition of that parameter....
You can for sure think... what if center is null in option A, you are right, that can happen, then you can take care of it by either throwing an illegalparameterexception, or just assigning that object to a default value. ..
But as I said before is my opinion..
I think it depends on your program. If you want the circle to have a reference to the MyPoint object, then you must pass it. Otherwise, why not pass in the actually x and y values themselves.
For example, option B can be written as:
public MyCircle(int x, int y, int radius) {
// rest
}
both options are fine, but as you told, an object may change in the time, the option A is ok when you want to modify the center in more than one object at the same time, for example in an List of Circles, but if you want to have unique and independient center points, option B is correct. So you why don't you have both constructors and use one or another depending many cases in your app, use whatever you want you consider better, keep both, it is my advice.
Hope it helps to you.
Related
I am stuck on my assignment and could use some help
In the instance variables section we are only allowed to use the following:
private int _width;
private int _height;
private Point _pointSW; // point is basically (x,y)
I have created a constructor but I am now confused on how can I create a _pointNW variable inside the constructor that I can later use in a "getter" method, here is my constructor, do note that I am not sure how to create _pointNW properly since its the first time I have no private variable to connect them so I am clueless on how exactly to do this properly and I was also worried about aliasing so I'm not sure if I had to use new here:
public RectangleA(Point sw, Point ne) {
_pointSW = new Point(sw);
Point _pointNW = new Point(ne);
}
I am not allowed to add _pointNW to the private section so it also confused me how exactly do I set it up in the constructor so I can in the end use it in a getter?
in the end I am supposed to retrieve that _pointNW to be used in the following "getter" :
public Point getPointNE(){ }
Anyone can help? been trying stuff out for an hour and can't figure out how to do this...
I think the idea of the assignment is to create a getter for the NE point without storing. That means you will have to store the information you need to calculate that point in the getter. You can use height and width to do this:
import java.awt.Point;
public class RectangleA {
private int _width;
private int _height;
private Point _pointSW;
public RectangleA(Point sw, Point ne) {
// This assumes (0,0) is in the nw corner
this._pointSW = new Point(sw); // Save the coordinates of the sw point
this._width = ne.x - sw.x; // Save the width based on the difference between the two points' x values
this._height = sw.y - ne.y; // Save the height based on the difference in y values
}
public Point getPointNE() {
// We don't store the ne point so we calculate it based on the sw point and the height and width
int neX = this._pointSW.x + this._width; // The sw x + width is the ne X coordinate
int neY = this._pointSW.y - this._height; // The sw y - height is the ne Y coordinate
Point result = new Point( neX, neY ); // construct that point and return it
return result;
}
}
One way is to create a new instance variable. But it seems you don't want to do that due to the assignment.
The other way is to calculate it in the getter. You have the SW point, the width, and the height. So you can either add or subtract the width and height to figure out the NE point. Whether you add or subtract would depend on where the origin is, you didn't specify.
So you have N/E (top/right) and S/W (bottom/left), N/W (top/left) is a combination of these two, for example
public Point getPointNW() {
return new Point(_sw.x, _ne.y);
}
I am writing code that is meant to use one given point of a perfect right triangle to find the remaining two. We assume for this exercise that it is a triangle like so: righttriangle
The first bit of code uses the Point2D class to establish the bottom left point like so:
public Triangle(Point2D.Double bottomLeftPoint, double height, double base){
this.base = base;
this.height = height;
this.bottomLeftPoint = bottomLeftPoint;
}
public Point2D.Double getBottomLeftTrianglePoint() {
return this.bottomLeftPoint;
}
I know that mathematically, the top point of the triangle would have the same x value, but would have the y value added by the height. Also the bottom right point would have the same y value but the x value added by the base.
My question is for method purposes, how would I structure that?
Would it be something like:
public Point2D.Double getTopTrianglePoint() {
return this.bottomLeftPoint(x, y + this.height);
}
public Point2D.Double getBottomRightTrianglePoint() {
return this.bottomLeftPoint(x + this.base, y);
}
For further info, I have a separate class that is meant to test the methods with with a test triangle:
public class TriangleTest {
private Triangle triangle01;
public TriangleTest() {
this.triangle01 = new Triangle(new Point2D.Double(1, 2), 5, 3);
}
}
Any help is appreciated. Thanks!
return this.bottomLeftPoint(x, y + this.height);
Break this down, then you'll notice this doesn't make sense. this.bottomLeftPoint is a variable of type Point2D.Double. You then.. try to treat this as a method somehow. It's not. This doesn't work.
You want to create an entirely new Point2D.Double. new Point2.Double(x, y) as per usual; Thus:
return new Point2D.Double(x, y + this.height);
Except, of course, if you try this, the compiler will tell you this doesn't work either; the compiler has no idea what x means. So, what do you intend to use there? Clearly it's the x coordinate of the Point2D.Double object referenced by your this.bottomLeftPoint field. Which has a .getX() method. So:
return new Point2D.Double(bottomLeftPoint.getX(), bottomLeftPoint.getY() + height);
I am learning Classes and Objects, and I am on reference variables, and accessing an object's data and methods. In my textbook, we created a program which calculates the area of a circle, given the radius.
They declare the object reference variable, create an object, and assign the reference to a variable here:
Circle myCircle = new Circle();
They later give an example below of finding the area (getArea()* just returns the area given the radius):
System.out.println("Area is " + new Circle(5).getArea());
Is the 5 (number in parentheses) an input for the radius?
If so, why isn't it in the getArea() parentheses?
Also, there are no arguments for Circle() so how can you have a number in the () anyway?
*Code for getArea():
By the way, could you get rid of the parentheses if there is only one statement inside?
double getArea()
{
return radius * radius * Math.PI;
}
Please excuse the horrid formatting - I wasn't able to use Ctrl-K, could someone edit it for me please.
Is the 5 (number in parentheses) an input for the radius?
System.out.println("Area is " + new Circle(5).getArea());
Not exactly.
It is the argument passed to a Circle constructor that should very probably value a radius field.
If so, why isn't it in the getArea() parentheses?
getArea() is an instance method of Circle. It relies on the state of the Circle instance that has already a radius information.
So passing a radius argument to getArea() makes no sense.
It would make sense if you had a utility static method in the Circle class to compute a area according to a radius.
For example :
public static double computeArea(double circleRadius){
...
}
You could invoke it in this way :
double area = Cicle.getArea(5.5);
Also, there are no arguments for Circle() so how can you have a number
in the () anyway?
Without a Circle constructor that accepts a radius information, the invocation new Circle(5) cannot compile. So it of course requires one.
You should have a Circle constructor defined such as :
public class Circle{
...
private double radius;
public Circle(double radius){
this.radius = radius;
}
}
by the way, could you get rid of the parentheses if there is only one
statement inside?
Parenthesis () refers to a specification of the Java language to declare method and constructor.
When you declare a method, you need it in any case.
I will try to explain in deep:
public class Circle {
// this variable can access only inside class
private final double radius;
// constructor for class Circle
public Circle(double rad) {
radius = rad;
}
// method of class Circle - can be access outside
public double area() {
return radius*radius*Math.PI;
}
}
when you instantiate class Circle as Circle circle5 = new Circle(5); you got instance of class Circle with encapsulated parameter radius = 5 now, you don't know any details, and just call method double area = circle5.area() to get the area of circle (rad*rad*Pi).
This is dramatically decrease complexity. Even in this very simple example.
now you can print you result
System.out.println(area);
I think, you got the idea.
1st step: you instantiated class and encapsulated all details into it via constructor;
2nd step: you can use you class (methods of the class) and never aware about implementation detail.
And in you sample, calling constructor without parameters new Circle() instead new Circle(5) - this is typographic mistake.
First let me explain constructors in Java.
There are two types of constructors in java: 1. Explicit and 2. Implicit.
Explicit means a constructor with argument and developed by developer.
Implicit means, default or non parameter constructor.
In your case let me analyse the operation:
System.out.println("Area is " + new Circle(5).getArea());
new Circle(5), actually means that invoking a n explicit constructor with input parameter 5.
According to your shared knowledge, it can be understood that a radius is set in this explicit constructor.
I mean, the following constructor should be exist:
public Circle(int i) {
radius = i;
}
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);
I don't know how to complete this. I'm learning by myself and I found this exercise where you have a class for a rectangle like this:
public class Rectangulo {
private int x, y, width, heigth;
public Rectangulo(int x, int y, int width, int heigth){
this.x = x;
this.y = y;
this.width = width;
this.heigth = heigth;
}
public boolean isOverlaping(Rectangulo r1, Rectangulo r2){
}
And I have to complete the method so it returns true if the 2 rectangles are overlapping / colliding or false if they aren't. Can you give me any guide to help me think this problem, or tips?
I don't have to use the intersects method.
Thanks!
If you look at the method, you're provided with two rectangle objects as arguments, r1 & r2. Each instance has its specific value for x,y, width and height. You can use these values to determine whether the two rectangles collide or overlap
For your specific doubt, you might want to read the javadoc for Rectangle.. This will help you understand how a rectangle is created in Java