Search | Synergex.com | Contact Us | Resource Center Login | Home|
News

What is the output of the following program?

namespace colors

    public class Color

      public method Color
      in req a_red, int
      in req a_green, int
      in req a_blue, int
      proc
        m_red = (a_red & ^x(ff))
        m_green = (a_green & ^x(ff))
        m_blue = (a_blue & ^x(ff))
      endmethod

      public virtual property RgbValue, int
        method get
          proc
            mreturn m_red | (m_green * ^x(100)) | (m_blue * ^x(10000))
          endmethod
      endproperty

      public static method op_Addition, @Color
      in req a_color1          ,@Color
      in req a_color2          ,@Color
      proc
        mreturn new Color(a_color1.m_red|a_color2.m_red,
        &                   a_color1.m_green|a_color2.m_green,
        &                   a_color1.m_blue|a_color2.m_blue)
      endmethod

      protected m_red, int
      protected m_green, int
      protected m_blue, int

    endclass

    public class TransparentColor extends Color

      public method TransparentColor
      in req a_alpha, int
      in req a_red, int
      in req a_green, int
      in req a_blue, int
        parent(a_red,a_green,a_blue)
      proc
        m_alpha = (a_alpha & ^x(ff))
      endmethod

      public override property RgbValue, int
        method get
          proc
            mreturn parent.RgbValue | (m_alpha * ^x(1000000))
          endmethod
      endproperty

      public static method op_Addition, @TransparentColor
      in req a_color1,         @TransparentColor
      in req a_color2,         @Color
      proc
        mreturn new TransparentColor(a_color1.m_alpha,
        &                                a_color1.m_red|a_color2.m_red,
        &                                a_color1.m_green|a_color2.m_green,
        &                                a_color1.m_blue|a_color2.m_blue)
      endmethod

      protected m_alpha, int

    endclass

endnamespace

main
record
  black  ,@Color
  blue   ,@TransparentColor
  which ,@Color
proc
  open(1,o,"TT:")
  black = new Color(2,2,2)          ;Almost black
  blue = new TransparentColor(42,0,0,255)   ;A translucent blue
  which = black + blue
  writes(1,hex(which.RgbValue))
end

a. 42FF0202
b. 2AFF0202
c. 00FF0202
d. This does not compile

Explanation
In this example, we provide a simple Color class that enables you to compose an RGB color value from red, green, and blue components. It also provides an overload for the “+” operator that mixes the two colors by combining the intensities of those three components.

Next, we derive a TransparentColor class that adds an alpha component (for transparency). When adding a Color (or another TransparentColor) to a TransparentColor, we want to keep the transparency of the original while mixing the color components the same as we did for Color.

In our usage example, we add a Color and a TransparentColor. Because the first operand is a Color, the argument signature for the TransparentColor.op_Addition method does not match, because it defines the first argument as a TransparentColor. Instead, Color.Addition is called (because a TransparentColor is also a Color), so the transparency value is lost. Thus, (c) is the correct response.

If we had wanted (b) instead, we could have done one of two things: (1) change “black + blue” to “blue + black”, or better yet, (2) define another version of TransparentColor.op_Addition that defines the arguments as Color and TransparentColor, in that order. Otherwise, you need to know which is which and who is who.

As you can see, it’s very easy to define an overload that makes addition not commutative. That’s counterintuitive for even a first-grade mathematician and should be avoided. In a case like the above, it’s probably more intuitive to avoid operator overloading altogether and create a virtual Mix() method instead. Reserve overloading mathematical operators for instances in which they have clear mathematical meaning and utility, and then ensure the consistency of their behavior.

More information about News and Events

Contact Synergex to learn more about  News and Events
Talk to Us: Synergy/DE instant call-back

Looking to extend the power of your Synergy/DE-based applications? Click the Synergy/DE instant call-back button to talk to us.