Object methods

Figure 218. Object methods Slide presentation Create comment in forum
Change an object's state.

Example: Scale a rectangle.

Get dependent values

Example: Calculate a rectangle's perimeter.

Combined

Scale a rectangle and calculate its new perimeter.


Figure 219. Scaling a rectangle Slide presentation Create comment in forum
Scaling a rectangle

Figure 220. Scaling method implementation Slide presentation Create comment in forum
public class Rectangle {
    int width, height;
    boolean hasSolidBorder;

    public void scale (int factor) {
        width *= factor;
        height *= factor;
    }
}
Scaling method implementation

Figure 221. Scaling method signature Slide presentation Create comment in forum
void  scale (int factor ) {
...}

No value is being returned to caller.

A single value of type int is being provided as method argument.


Figure 222. Using scale(...) method Slide presentation Create comment in forum
Rectangle r = new Rectangle();
r.width = 33;
r.height = 22;

r.scale(2);

System.out.println("width=" + r.width);
System.out.println("height=" + r.height);
width=66
height=44

Figure 223. Method definition syntax Slide presentation Create comment in forum
public  void  scale (int factor ) { 
   width *= factor; 
   height *= factor;
}
[access modifier]  return_type  methodName  ([arguments] ) {
   [statement(s)] 
}

Optional access control modifier either of public, protected or private.

The method's return type either of:

void

The method will not return a value on completion.

A data type e.g. int, double, ...

The method will return a value of the given type to its caller.

The method's name.

Arguments being required for execution.

Start of method's body.

The method's implementation.


Figure 224. A rectangle's perimeter Slide presentation Create comment in forum
A rectangle's perimeter

Figure 225. Get perimeter implementation Slide presentation Create comment in forum
public class Rectangle {
    int width, height;
    boolean hasSolidBorder;

    public void scale (int factor) { ... }

    public int getPerimeter() {
        return 2 * (width + height);
    }
}
Get perimeter implementation

Figure 226. Using Rectangle.getPerimeter() Slide presentation Create comment in forum
Rectangle r = new Rectangle();

r.width = 33;
r.height = 22;

System.out.println("Perimeter=" + r.getPerimeter());
Perimeter=110

exercise No. 81

Modeling geometry objects: Rectangles Create comment in forum

Q:

We want to represent rectangles being defined by width and height to allow for the subsequently demonstrated operations:

final Rectangle r = new Rectangle(8, 5); 

System.out.println("Perimeter:" + r.getPerimeter());
System.out.println("Area:" + r.getArea());

r.setWidth(4); 
r.setHeight(7);

System.out.println("Perimeter:" + r.getPerimeter()); 
System.out.println("Area:" + r.getArea());

Creating an instance of class Rectangle by calling a non-default constructor which allows for providing width (8) and height (5).

Returning the rectangle's perimeter,

Returning the rectangle's area.

Setting with and height to new values.

Write (possibly) changed perimeter and area values.

You may start from the following Rectangle class dummy implementation:

/**
 * Representing rectangular shapes.
 *
 */
public class Rectangle {

  /**
   *
   * @param width The rectangle's width
   * @param heigth The rectangle's height
   */
  public Rectangle (double width, double heigth) {
     //TODO
  }
  /**
   * @return The rectangle's area.
   */
  public double getArea() {
    return 0; // TODO
  }

  /**
   * @return The rectangle's perimeter.
   */
  public double getPerimeter() {
    return 0; // TODO
  }

  /**
   * @return The rectangle's width.
   */
  public double getWidth() {
     return 0; // TODO
  }
  /**
   * @param width The rectangle's new width
   */
  public void setWidth(double width) {
      // TODO
  }

  /**
   * @return The rectangle's height.
   */
  public double getHeight() {
     return 0; // TODO
  }

  /**
   * @param height The rectangle's new height
   */
  public void setHeight(double height) {
      // TODO
  }
}

A:

First we define two instance variables width and height representing a Rectangle's corresponding two parameters width and height:

public class Rectangle {

  // Instance variables representing a rectangle's parameters
  private double width, height;
...
}

Next we allow for changing these two parameters:

public class Rectangle {

  // Instance variables representing a rectangle's parameters
  private double width, height;

...
  /**
   * @param width Changing the rectangle's width
   */
  public void setWidth(double w) {
      width = w;
  }

  /**
   * @param width Changing the rectangle's height
   */
  public void setHeight(double height) {
      this.height = height;
  }
...
}

Note the subtle implementation difference between setWidth(...) and setHeight(...):

setWidth(double w)

We use the formal parameter name w. Its name does not conflict with the instance variable name width being defined at class level. We can simply assign this value to our corresponding instance variable using width = w;.

setHeight(double height)

The method's formal parameter height shadows the instance variable's name being defined at class level. We need the this keyword in this.height = height to resolve the ambiguity.

Both ways are perfectly legal. The complete implementation including all remaining methods reads:

/**
 * Representing rectangular shapes.
 *
 */
public class Rectangle {

  // Instance variables representing a rectangle's parameters
  private double width, height;

  /**
   *
   * @param width The rectangle's width
   * @param heigth The rectangle's height
   */
  public Rectangle (double width, double height) {
     setWidth(width);
     setHeight(height);
  }
  /**
   * @return The rectangle's area.
   */
  public double getArea() {
    return width * height;
  }

  /**
   * @return The rectangle's perimeter.
   */
  public double getPerimeter() {
    return 2 * (width + height);
  }

  /**
   * @return The rectangle's width.
   */
  public double getWidth() {
     return width;
  }
  /**
   * @param width The rectangle's new width
   */
  public void setWidth(double w) {
      width = w;
  }

  /**
   * @return The rectangle's height.
   */
  public double getHeight() {
     return height;
  }

  /**
   * @param width The rectangle's new height
   */
  public void setHeight(double height) {
      this.height = height;
  }
}

exercise No. 82

Modeling circles Create comment in forum

Q:

This exercise is very similar to Modeling geometry objects: Rectangles . With respect to the upcoming section on inheritance its presence will be justified later by the section called “Geometry classes reconsidered”.

We provide a corresponding class Circle dummy implementation:

package step1.dummy;

/**
 * A circle of given radius
 *
 */
public class Circle {

  /**
   * A new circle
   *
   * @param radius
   *          The desired radius.
   */
  public Circle(double radius) {
    // TODO
  }

  /**
   * @return The circle's area.
   */
  public double getArea() {
    return 0; // TODO
  }

  /**
   * @return The circle's perimeter.
   */
  public double getPerimeter() {
    return 0; // TODO
  }

  /**
   * @return The circle's radius.
   */
  public double getRadius() {
    return 0; // TODO
  }

  /**
   * @param radius
   *          Setting the circle's radius to a new value.
   */
  public void setRadius(double radius) {
    // TODO
  }
}

Instances of this class shall be usable in the following fashion:

public static void main(String[] args) {
  final Circle c = new Circle(2.3);

  System.out.println("Radius:" + c.getRadius());
  System.out.println("Perimeter:" + c.getPerimeter());
  System.out.println("Area:" + c.getArea());

  // Changing the circle's radius to a different value
  c.setRadius(4.7);

  System.out.println("Radius:" + c.getRadius());
  System.out.println("Perimeter:" + c.getPerimeter());
  System.out.println("Area:" + c.getArea());
}

Hint: Obviously you'll have to define an instance variable within Circle to keep track of its current radius value. All methods mentioned above simply depend on this single value.

A:

We define an instance variable radius inside our class Circle:

public class Circle {

  double radius;
...
}

Next we implement our method to change a circle's radius:

public void setRadius(double r) {
  radius = r;
}

Note that we have chosen a different value for the method's formal radius parameter to be r rather than radius. Many people prefer to use radius here making it easier for a programmer to recognize the expected name in the generated Javadoc:

public void setRadius(double radius) {
  this.radius = radius;
}

This requires the usage of the this keyword to distinguish the formal parameter in setRadius(double radius) from the instance variable previously being defined within our class Circle. In other words: We have to resolve a name shadowing conflict.

The rest of the implementation is (quite) straightforward. A complete class reads:

package step1;

/**
 * A circle of given radius
 *
 */
public class Circle {

  double radius;

  /**
   * A new circle
   * @param radius The desired radius.
   */
  public Circle(double radius) {
    setRadius(radius);
  }

  /**
   * @return The circle's area.
   */
  public double getArea() {
    return radius * radius * Math.PI;
  }

  /**
   * @return The circle's perimeter.
   */
  public double getPerimeter() {
    return 2 * Math.PI * radius;
  }

  /**
   * @return The circle's radius.
   */
  public double getRadius() {
    return radius;
  }

  /**
   * @param radius Setting the circle's radius to a new value.
   */
  public void setRadius(double radius) {
    this.radius = radius;
  }
}

exercise No. 83

Adding translations and SVG export. Create comment in forum

Q:

We want to add more features to tour Circle and Rectangle classes:

Translations

Add two more instance variables x and y and corresponding setter methods to account for a shape's translation vector with respect to the origin (0,0). The following hint may be helpful:

/**
 * @param x The circle's x center coordinate value
 */
public void setX(double x) {
  // TODO
}
/**
 * @param y The circle's y center coordinate value
 */
public void setY(double y) {
  // TODO
}

You may as well extend the constructors of Rectangle and Circle to accept center coordinates as well:

public class Rectangle {

...
   /**
    * Rectangle having center coordinates x, y, width and height.
    *
    * @param x The rectangle center's x-coordinate
    * @param y The rectangle center's y-coordinate
    * @param width The rectangle's width
    * @param height The rectangle's height
    */
   public Rectangle(double x, double y, double width, double height) {
     ...
   }
  ...
}
public class Circle {
   ...

   /**
    * Circle having center coordinates x, y and radius r.
    *
    * @param x The circle center's x-coordinate
    * @param y The circle center's y-coordinate
    * @param radius The circle's radius
    */
   public Circle(double x, double y, double radius) {
     ...
   }
  ...
}
SVG export

We would like Rectangle and Circle instances to be visualized as SVG graphics. SVG Examples provides editor samples both for circles and rectangles. Add a method void writeSvg() to both of your classes which allows for SVG code being written to standard output. Use System.out.println(...) calls to create the desired SVG output. You may need \" to escape double quotes as in the subsequent example or use single attribute quotes instead:

System.out.println("<rect width=\"20\"" ...

The following code snippet may serve to illustrate the intended use of void writeSvg():

public class Driver {

  public static void main(String[] args) {

    System.out.println("<!DOCTYPE html><html><body>");
    System.out.println("  <svg width='300' height='200' >");

    // Draw a rectangle as SVG
    final Rectangle r = new Rectangle(5, 4);
    r.setX(2);
    r.setY(1);
    r.writeSvg();

    // Draw a circle as SVG
    final Circle c = new Circle(3);
    c.setX(3);
    c.setY(1);
    c.writeSvg();
    System.out.println("  </svg >");
    System.out.println("</body></html>");
  }
}

Implement the method void writeSvg() in both classes Rectangle and Circle. The following sample export is intended for 300x200 pixel requiring to scale e.g. the above circle's radius of three by a factor of 20 resulting in an effective <circle r='60' .../> value. This scaling is being required for all parameters:

<!DOCTYPE html>
<html>
  <body>
    <svg width='300' height='200' >
      <rect width='100.0' height='80.0' x='40.0' y='20.0'
            style='fill:rgb(0,255,0);stroke-width:3;stroke:rgb(0,0,0)'/>
      <circle r='60.0' cx='60.0' cy='20.0'
            style='fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)'/>
      </svg >
  </body>
</html>

You may copy this output into a file svg.html. A web browser should visualize this output as:

A:

public class Rectangle {

  private double x, y, width, height;
 ...
  /**
   * @param x The rectangle's x center coordinate value
   */
  public void setX(double x) {
    this.x = x;
  }
  /**
   * @param y The rectangle's y center coordinate value
   */
  public void setY(double y) {
    this.y = y;
  }

public void writeSvg() {
    final int scale = 20;
    System.out.println(
        "<rect width='" + scale * width +"' height='" + scale * height +
        "' x='" + scale * x + "'" + " y='" + scale * y + "'" +
        "' style='fill:rgb(0,255,0);stroke-width:3;stroke:rgb(0,0,0)'/>");
  }
}
public class Circle {

  double x, y, radius;
...

  /**
   * @param x The circle's x center coordinate value
   */
  public void setX(double x) {
    this.x = x;
  }
  /**
   * @param y The circle's y center coordinate value
   */
  public void setY(double y) {
    this.y = y;
  }

public void writeSvg() {
  final int scale = 20;

    System.out.println(
        "<circle r='" + scale * radius +
        "' cx='" + scale * x + "'" + " cy='" + scale * y +
        "' style='fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)'/>");

  }
}