[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[jfriends-ml 10151] Re: 動的実行メソ ッド決定はなぜされないのか



柴田です。

次回は、特にエントリーしませんが、午前中からは参加できなかもしれません
が、できるだけ午後からは、参加したいと思います。

> 本の項目7には、
> 
> public class MyClass {
>   public boolean equals(Object another) {
>     if (!(another instanceof MyClass)) {
>       return false;
>     }
>     :
>   }
> }
> 
> みたいにして判定していますが、メソッド引数にもポリモーフィズムを適用して、
> 
> public class MyClass {
>   public boolean equals(Object another) {
>     return false;
>   }
>   public boolean equals(MyClass another) {
>     if (another == null) {
>       return false;
>     }
>     :
>   }
> }
> 
> と書いた方がすっきりするし応用が利くのでは? と思ったりする時があります。


細かいことですが、この実装では、項目7の最後の段落に書かれている「2つのメ
ソッドが同じ結果を返す限り、受け入れられますが」に反していますね。

> ただし、呼び出すメソッドはコンパイル時に決まってしまうため、
> 
> (1)
>   MyClass foo = new MyClass();
>   MyClass bar = new MyClass();
>   boolean fooEqualsBar = foo.equals(bar);
> 
> と書けば、MyClass#equals(MyClass)メソッドが呼ばれますが、
> 
> (2)
>   MyClass foo = new MyClass();
>   Object bar = new MyClass();
>   boolean fooEqualsBar = foo.equals(bar);
> 
> と書くと、barはMyClassオブジェクトのインスタンスですが、型宣言がObject型
> であるために、MyClass#equals(Object)メソッドが呼ばれます。
> (実行時の型に影響されない)

上記の実装では、(2)のケースでequals(Object)が呼び出された時に、本当なら
trueを返すべき時に、falseを返すことになります。あるいは、もっと分かり易
くすると

 MyClass foo = new MyClass();
  Object bar = foo;
  boolean fooEualsBar = foo.equals(bar);

でfalseになってしまいますね。そして、bar.equals(foo)はtrueになってしまい
ますね。