views:

83

answers:

3

Hello there,

I'm in my first OOP class and I really like it, but on this assignment, I'm not really sure what the best (most efficient, less code, etc.) way to use constructors in this situation? Preferably using constructor chaining.

A little more info:

  • I would like my default constructor to create & initialize all the objects shown in my code snippet

  • Then I would like my parameratized constructor to call the default constructor, thus creating and initializing those objects, that can then be used in the parameratized constructor without getting a NullReferenceException

Again, I have a very elementary understanding of constructors, so if this is not possible, then please just tell me so, and tell me what you would do in this situation.

Thanks!

    class Rectangle
    {
    public Line left { get; set; }
    public Line top { get; set; }
    public Line right { get; set; }
    public Line bottom { get; set; }

    public Rectangle() : this(new Line()) { }

    public Rectangle(Line diagnonal) 
    {
         left = new Line();
         top = new Line();
         right = new Line();
         bottom = new Line();

    Point beginningDiagonalPoint = new Point();
    Point endingDiagonalPoint = new Point();

    beginningDiagonalPoint = diagnonal.startPoint;
    endingDiagonalPoint = diagnonal.endPoint;

    int begXC = beginningDiagonalPoint.xCoord;
    int begYC = beginningDiagonalPoint.yCoord;

    int endXC = endingDiagonalPoint.xCoord;
    int endYC = endingDiagonalPoint.yCoord;

    Point rightSideEnd = new Point();

    rightSideEnd.xCoord = endXC;
    rightSideEnd.yCoord = begYC;

    Point leftSideEnd = new Point();

    leftSideEnd.xCoord = begXC;
    leftSideEnd.yCoord = endYC;

    // ----------- right side definitions -------------
    right.startPoint = endingDiagonalPoint;
    right.endPoint = rightSideEnd;

    // ------------ left side definitions --------------
    left.startPoint = beginningDiagonalPoint;
    left.endPoint = leftSideEnd;

    // ------------ top side definitions -------------
    top.startPoint = leftSideEnd;
    top.endPoint = endingDiagonalPoint;

    // ------------ bottom side definitions -----------
    bottom.startPoint = rightSideEnd;
    bottom.endPoint = beginningDiagonalPoint;
    }
    }
+1  A: 

Your example nearly does what you are asking for. The way you've done it, though, it's the default constructor that calls the paramaterized contructor, giving it a default parameter to work with. There's nothing wrong with doing it this way, it's just not what you said you were looking for.

Also, it's conventional for public properties to begin with capital letters (Left, Right, Top, Bottom instead of left, right, top, bottom). Notice that all the .NET library classes do it this way.

Nate C-K
+1  A: 

Your paramaterised constructor already initialises all your properties. So, I think all you need to do is pass some sort of default into the paramaterised constructor from your default constructor.

You need to answer this question yourself: what is a default or empty Rectangle? I'm going to assume it's a zero sized one.

So, presuming a Line takes two points as parameters, I'd do this:

public Rectangle() : this(new Line(new Point(0,0), new Point(0,0))) { }

And in a less condensed format:

public Rectangle() 
    : this(
          new Line(
              new Point(0,0), 
              new Point(0,0)
          )
      ) 
{ }
+1  A: 

Usually when you chain constructors it's the other way around: the default constructor calls the more specific constructors with the default values. Say, you have a Point constructor that takes the x and y coordinates. Then you have the default Point constructor call the other one with x = 0 and y = 0. This way you only have to write the code to set the values once.

Here are some things you can improve in your code:

  1. You initialize beginningDiagonalPoint and endingDiagonalPoint to new points and then you overwrite them with references to diagnonal.startPoint and diagnonal.endPoint. You are creating two new points and then discarding them. You don't need to create those new points.

  2. You create new Points and new Lines with the default constructor and then manually set their fields. You could create a point constructor that receives the two coordinates and sets them, and a line constructor that receives the two end points and sets them. Your code would look like this:

     Point rightSideEnd = new Point(endXC, begYC);
     Point leftSideEnd = new Point(begXC, endYC);
    
    
     right = new Line(endingDiagonalPoint, rightSideEnd);
     left = new Line(beginningDiagonalPoint, leftSideEnd);
     top = new Line(leftSideEnd, endingDiagonalPoint);
     bottom = new Line(rightSideEnd, beginningDiagonalPoint);
    
Martinho Fernandes