grauzone wrote:
Andrei Alexandrescu wrote:
Here's an article about the perils of equals in Java (opEquals in D):
http://www.ddj.com/article/printableArticle.jhtml;jsessionid=GFKUCQH5S4IHNQE1GHOSKHWATMY32JVN?articleID=184405053&dept_url=/java/
It turns out this is a great example for NVI. In D, we could and should
do the following:
class Object {
// Implement this
private bool opEqualsImpl(Object rhs) {
return false;
}
// Use this
final bool opEquals(Object rhs) {
if (this is rhs) return true;
if (this is null || rhs is null) return false;
return opEqualsImpl(rhs) && rhs.opEqualsImpl(this);
}
}
I took advantage of the fact that in a final function this may be null
without an access violation. The implementation above ensures symmetry
of equality and has each class implement a simpler primitive.
What do you think?
Eh, now after all this discussion, we're going to allow even "this" to
be null? That seems like a backstep...
How is it a backstep? It's perfectly valid behavior.
Object foo;
foo.opEquals(foo);
The call itself will *always* succeed, its when 'this' gets referenced
in opEquals that the code will crash.
Implementing opEquals as a global/static function, that calls the actual
Object.opEquals virtual method would be so much more straight forward.
I agree, I prefer methods to end with Impl to stay hidden instead of
being the ones to override.
PS: I agree about the NVI thing. If you'd go to extend the language for
"NVI", couldn't we just introduce a second type of virtual function that
works this way:
1. the super class' implementation is _always_ called first
2. the super class function can decide to "call down" to the sub class'
implementation of the same method
=> no extra do<something> method needed, and the code is (possibly)
clearer.
Andrei
I don't know how useful that would be, when you override a method you
usually want to call the super method somewhere in the new
implementation, not always at the beginning.