演算子のオーバーライドって ダックタイピング?

「Groovy イン・アクション」を読んでる。今 56 ページ だ。
ここで、演算子のオーバーライドの例が載っている。でダックタイピングって思ったのは、加算演算子がそうなのかなと。
本に載ってたコードの一部抜粋。

class Money { 
  private int amount
  private String currency
  Money (amountValue, currencyValue) {
    amount = amountValue
    currency = currencyValue
  }
  Money plus (Money other) {
    if (null == other) return null
    if (other.currency != currency) {
      throw new IllegalArgumentException("cannot add $other.currency to $currency")
    }
    return new Money(amount + other.amount, currency)
  }
}

def buck = new Money(1, 'USD')
assert buck + buck == new Money(2, 'USD')
assert buck - buck == new Money(0, 'USD')  // minus メソッドを実装していないので、実行時に例外が発生する。

plus ってメソッドを定義していたら、+演算子が使用出来る。minus ってメソッドを定義していたら、-演算子が使用出来る。
これって、ダックタイピング だよね?

assert buck + buck == new Money(2, 'USD')

ここは、内部的には、buck.plus(buck) 変換されるんだと思う、んで Money クラスは 「たまたま」plus メソッドが実装されてたから問題無い。
でも、

assert buck - buck == new Money(0, 'USD') // minus メソッドを実装していないので、実行時に例外が発生する。

ここは、内部的には、buck.minus(buck) に変換されて、Money クラスは minus メソッドが実装されていないから実行時例外が発生する。


C# の場合、演算子のオーバーロードを行うには、その型に static なメソッドを実装する必要がある。※チェック処理とかは省いてます。

public static Money operator + (Money m1, Money m2)
{
return new Money(m1.amount + m2.amount, m1.currency);
}


でも、Groovy の場合は、インスタンスが plus って操作を実行出来て、それを簡潔に記述するのに +演算子を使って表現するって形だと理解してる。(シンタックスシュガーって言うんだっけ?)
オブジェクト指向っぽい解決方法なのかな。


※関係無いけど、演算子のオーバーライドって違和感がある。これは、本書(「Groovy イン・アクション」P56)にも載ってた。

厳密な意味では加算演算子はオーバーライドされているわけではありません。〜(省略)このケースでは演算子実装が最も適切な表現でしょう。