サブクラスはスーパークラスを返却してもいいんじゃない?
「蒸し返し歓迎」ということで、2006年のエントリから。1ヶ月前くらいに読んで、ちょっと気になってたので。既に着地した話題ならすいません。
さてと、NonNegativeInteger extends IntNumber, Score100 extends IntNumberとしたとき、サブクラスであるNonNegativeIntegerとScore100は、リスコフ女史の教えに従ってプログラマをだますことができるでしょうか? -- NonNegativeIntegerでは、メソッドminusによっていずれ馬脚をあらわします。Score100は、plus, minus, timesのどれであれ、IntNumberとは食い違った挙動を示すでしょう。
クラス継承、リスコフの置換原則、部分集合の型 - 檜山正幸のキマイラ飼育記 (はてなBlog)
「NonNegativeIntegerのminusはIntNumberを返す」という定義が自然だと思うんですが、どうでしょう?NonNegativeIntegerのminusが受け取るパラメータもNonNegativeIntegerである必要はないですし。IntNumberに対する置換原則にも沿います。
「x.minus(y)」の結果がNonNegativeIntegerになるかどうかは、演算させる側(caller)の責任となるはずです。NonNegativeIntegerのminusメソッド内で、自身とパラメータの大小関係をチェックしてNonNegativeIntegerを返すかどうかを判断してもよいし、IntNumberオブジェクトの生成時に「正ならばNonNegativeIntegerクラスのオブジェクトを生成する」としてもよいし。演算結果のオブジェクトをどのクラスとして扱うかも、callerの自由です。
Score100は「評価の尺度としての100」であり、整数値とは異なる性格であって、整数の部分集合と考えるのがそもそも苦しいような気がします。Scoreクラスもサブクラスとして考えてもいいかも知れないけど。整数そのものとの足し引きはあんまりしないですよね。