I'm new(ish) to coding, so let's get that out of the way. Also, I'm currently using Java.
I want to instantiate a Line object in two different ways:
public Line(double x1, double y1, double x2, double y2){}//creates a line connecting two points and
public Line(double x, double y, double dir, double length){}//creates a line extending off of one point
However, they both have the same method header according to the compiler.
I considered adding a useless parameter to the second constructor, but that seems messy and unnecessary. Does anyone have any suggestions on how to deal with a problem like this one both now and in the future?
Note: This topic is only about fixing the header, not about how my code could be improved. Thanks!
You can create two different static factory method for both of those constructors calls.
According to Wikipedia :
The Factory Method design pattern is one of the "Gang of Four"
design patterns that describe how to solve recurring design problems
to design flexible and reusable object-oriented software, that is,
objects that are easier to implement, change, test, and reuse.
The Factory Method design pattern is used instead of the regular class
constructor for keeping within the SOLID principles of programming,
decoupling the construction of objects from the objects themselves
Factory methods are just essentially methods that can have different names (and not having to use the name of the class) and a different number of parameters or even the same number of parameters with a previous one. You can do something like this :
public static Line createJoining(double x1, double y1, double x2, double y2){...}
public static Line createExtending(double x1, double y1, double x2, double y2){...}
Then you could have a single constructor like this
public Line(double x1, double y1, double x2, double y2){}//creates a line connecting two points
Inside createJoining() and createExtending(), you could call this constructor,
and put your different program logic inside these two factory methods.
createJoining() and createExtending(), would have to return a new instance of Line like this:
public static Line createJoining(double x1, double y1, double x2, double y2){
// program logic goes here, where you can do some calculations
return new Line(x1, y1, x2, y2);
}
public static Line createExtending(double x1, double y1, double x2, double y2){
// program logic goes here, where you can do some calculations
return new Line(x1, y1, x2, y2);
}
Usage example,
Line joinedLine = Line.createJoining(0.1, 3.5, 10.5, 1.0);
Line extendedLine = Line.createExtended(0.6, 29.4, 20.0, 2.0);
More info about Factory Methods here
Another way is to avoid the same method header and at the same time use more meaningful parameter types:
import java.awt.geom.Point2D;
…
public Line(Point2D.Double p1, Point2D.Double p2) { … }
public Line(Point2D.Double p, double dir, double length) { … }
Related
Consider we have two class named Point and Line. And Line class has two constructors. This is code of Point class.
// The Point class definition
public class Point {
// Private member variables
private int x, y; // (x, y) co-ordinates
// Constructors
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public Point() { // default (no-arg) constructor
x = 0;
y = 0;
}
}
And this is code of Line class.
public class Line {
// Private member variables
Point begin, end; // Declare begin and end as instances of Point
// Constructors
public Line(int x1, int y1, int x2, int y2) {
begin = new Point(x1, y1);
end = new Point(x2, y2);
}`
public Line(Point begin, Point end) {
this.begin = begin;
this.end = end;
}
}
As you see Line class has two constructor. And First constructor is example of Compositon while second constructor example aggregation. Now, what can we say about this case? Can a class have both aggregation and composition? Thank for your answers.
A generally accepted definition of the difference between aggregation and composition is lifetime responsibility and ownership.
Aggregation: An object A holds references to other objects, but those other objects are shared with other classes. When A is disposed, the other objects continue to live and be used in the application
Composition: An object B is "made" of other objects. When A is disposed, so are the other objects.
It's worth quoting Fowler on this:
Few things in the UML cause more consternation than aggregation and composition
...
Aggregation (white diamond) has no semantics beyond that of a regular association. It is, as Jim Rumbaugh puts it, a modeling placebo
...
Composition (black diamond) does carry semantics. The most particular is that an object can only be the part of one composition relationship
So yes, a class can have both composition and aggregation relationships to the objects it holds references to, but possibly not as per the example you have shown.
Since the defining characteristic of composition (versus aggregation) is having exclusive/non-shareable parts (see https://stackoverflow.com/a/27889087/2795909), your example of a Point-Line part-whole relationship is clearly an aggregation (no matter if you pass the point objects to, or create them in, the constructor) since the two points definijng a line can be shared with other lines.
I am trying to write a translate method in a segment class. My variables are p1 = x1, y1 and p2 = x2, y2. How can I create a translate method using these two variables?
I wrote my translate method in my Point class as:
public void translate(int xmove, int ymove) {
x += xmove;
y += ymove;
}
Here my variables are x and y, simple! But for my segment class I am confused and not sure how to put them in the code.
If this is a geometric segment, then it ought to be defined in terms of two Points (a line segment) or two Points and a radius (circular segment), or something along those lines.
In that case, it should have some private fields that store the Point data. Translating the whole segment just means translating each Point in the class.
So if it's a line segment, and you have
class Segment {
Point start;
Point end;
//...
}
then you'd just need
class Segment {
Point start;
Point end;
public void translate(int xmove, int ymove) {
start.translate(xmove,ymove);
end.translate(xmove,ymove);
}
}
This is good design because it reuses your Point class in defining the Segment, and uses Point methods to define Segment methods.
But it does depend a little on quite what you mean by "segment"...
I am not 100% sure this is what you want, but assuming you would like to translate a segment of 2 points
class Segment{
Point point1;
Point point2;
//constructor
public void translateSegment(int xmove, int ymove){
point1.translate(xmove,ymove);
point2.translate(xmove, ymove);
}
}
If you change the method in the point class to private, you will need to do something else. This code is based on the fact that your translate method for a point is public. There are advantages and disadvantages to having an object mutable, and this is a design question you should consider.
I have a segment class with includes a bunch of codes. I have stuck on using two methods, isParallel and shorten methods. Here is my code so far(I have a point class as well which linked to this class):
public class Segment {
//two Points that hold endpoints of the segment
private Point p1, p2;
//Default constructor that will set the endpoints to new
//Points with values (0,0) and (4,4)
public Segment(){
this(0, 0, 4, 4);
}
//Parameterized constructor that accepts (int x1, int y1, int x2, int y2)
//and creates and sets the endpoints
public Segment(int x1, int x2, int y1, int y2){
this.p1 = new Point(x1, y1);
this.p2 = new Point(x2, y2);
}
//Parameterized constructor that accepts (Point p1, Point p2) and sets both
//the endpoints to a deep copy of the Points that are passed in.
public Segment( Point p1, Point p2){
this.p1 = new Point(p1.getX(), p1.getY());
this.p2 = new Point(p2.getX(), p2.getY());
}
//Copy constructor that accepts a Segment and initializes the data (of the
//new Segment being created) to be the same as the Segment that was received.
public Segment(Segment other){
p1 = other.getP1();
p2 = other.getP2();
}
public Point getP1(){
return p1;
}
public Point getP2(){
return p2;
}
//The length method returns the length of the Segment.In fact, this method is same as distanceTo method
//So we can use distanceTo method which is already defined in Point class
public double length(){
return (p1.distanceTo(p2));
}
//The translate method returns nothing and should translate, or shift,
//itself (the Segment) by the distances passed in
public void translate(int xmove, int ymove) {
p1.translate(xmove,ymove);
p2.translate(xmove,ymove);
}
//The midpoint method calculates and returns the midpoint of the Segment as a new Point
public Point midpoint(){
return (p1.halfWayTo(p2));
}
//The slope method returns the slope of the Segment as a double.
public double slope(){
return (double)(p2.getY() - p1.getY()) / (p1.getX() - p2.getX());
}
/**
* The isParallel method returns true/false depending on whether the current Segment
* is parallel to the Segment received. Think about how you can tell if two segments
* are parallel. Note: Two overlapping segments ARE parallel.
*/
public boolean isParallel( Segment s1 ){
{
/**
* The shorten method changes its (the Segment's) endpoints so that they are both halfway
* to the midpoint. Example: The segment (0,0)---(12,16) has midpoint (6,8). After
* calling the shorten method, the segment should be (3,4)---(9,12). Each endpoint
* has moved in toward the midpoint (which stayed the same). So (3,4) is halfway between
* (0,0) and (6,8) and (9,12) is halfway between (12,16) and (6,8).
*/
public void shorten();
Can someone give me an idea of how to use these two methods in my code. I really appreciate your help.
Thank you!
I am actually working on the same exact assignment! For the isParallel method, you need to check and see if the current Segment's slope is the same as the slope of the Segment received. I haven't worked on the shorten method so I can't help you with that yet.
Also, in my class (since I'm doing the same assignment), we aren't suppose to use the getX() and getY() methods since they defeat the whole purpose of learning about encapsulation. We need to actually ask the Point class to calculate the information for the points. For example, with the slope method instead of returning return (double)(p2.getY() - p1.getY()) / (p1.getX() - p2.getX());, I made a method inside of Point to calculate the slope of two points called calcSlope. And to call that method within the Slope method inside Segment: return p1.calcSlope(p2);.
Hopefully that helps!
Looking to use one variable to define an x1, x2, x3, x4 for a method. Is there a type that exists that would allow me to do this? I could just do 2 Points, but I'd rather just have one variable. If one doesn't exist, am I able to create a type similar to this that I can make useable in all classes in my package?
Thanks!
Have you considered defining your own tuple?
public class PointsTuple
{
public Point Point1;
public Point Point2;
// replace with appropriate setters and getters if you want.
}
Hopefully you will give your class a more descriptive name than PointsTuple but you get the idea. Here I used public fields but if you are familiar with encapsulation you may opt to use set & get methods.
Yes! The rectangle!
java.awt.rectangle
Rectangle(int x, int y, int width, int height)
Example:
Rectangle r = new Rectangle(x1, y1, x1-x2, y1-y2)
Try making a custom class like this:
class MyPoint{
private int x1;
private int x2;
private int x3;
private int x4;
//Setters and Getters for the points
}
I am an AP java student and while working on a project I wondered if it is a good practice to have a parameter that is a global variable. If you're wondering why I would want to do that well is so I wouldn't have to do this:
public class Circle {
private DrawingTool pen;
private SketchPad paper;
private double myX;
private double myY;
private double myWidth;
private double myHeight;
public Circle(double x, double y, double width, double height){
paper = new SketchPad(500,500);
pen = new DrawingTool(paper);
x = myX; //I don't want to have to assign this every time
y = myY; //like here
width = myWidth; // and here
height = myHeight; // and here
}
}
is it allowed to just do the following:
public Circle(double myX, double myY, double myWidth, double myHeight){
paper = new SketchPad(500,500);
pen = new DrawingTool(paper);
}
}
and every time I pass the arguments to the parameter they will automatically be assigned to the global variables?
and every time I pass the arguments to the parameter they will automatically be assigned to the global variables?
No. There's nothing within Java which will make the "parameter to instance variable" (which isn't really "global") assignment automatic. Many IDEs have the ability to generate the code for you, but it does need to be there.
An object stores its state in fields (variables in some programming languages) and exposes its behavior through methods (functions in some programming languages). Methods operate on an object's internal state and serve as the primary mechanism for object-to-object communication. Hiding internal state and requiring all interaction to be performed through an object's methods is known as data encapsulation — a fundamental principle of object-oriented programming.
Source: What Is an Object?