Implementing abstract methods should not require the "override" attribute, IMO
via Digitalmars-d
digitalmars-d at puremagic.com
Sat Jun 14 10:13:51 PDT 2014
Suppose you are sketching out your application, and you decide
that you need two classes, A and B. You know that instances of
both classes will be asked to foo things up, so you tell the type
checker that both A and B are foo-uppers:
interface Foo
{
void foo();
}
class A : Foo
{
void foo() { /* ... */ }
}
class B : Foo
{
void foo() { /* ... */ }
}
Later, you decide that A and B should also be able to, say,
un-foo things up. Now that you think about it, A and B un-foo
things up in exactly the same way, so you might as well reuse the
code. So you decide to tweak your design as follows:
class Foo
{
abstract void foo();
void unfoo() { /* ... */ }
}
class A : Foo
{
void foo() { /* ... */ }
}
class B : Foo
{
void foo() { /* ... */ }
}
Seems like a reasonable first iteration on your design, but the
compiler complains: A and B are overriding Foo's foo() without
using "override". Is this a reasonable complaint from the
compiler? I argue it is not, both conceptually and practically.
1) While you now inherit from a class, instead of implementing an
interface, conceptually it still feels like you are implementing
the foo() part of an interface. Unlike C++, our "pure virtual"
Foo.foo function can't even have a definition, so to speak of us
being overriding something seems like a legalism at best --- it
may be true by definition, if you so define it, but it doesn't
seem like a particularly meaningful definition.
2) The practical advantage of having an "override" attribute is
to express your intent, so that if you fail to match the method
signature the compiler will notice the slip-up and tell you so,
before further damage is done. But if you fail to match the
signature this is very likely to be noticed, because your derived
class will be abstract, and thus cannot be instantiated.
More information about the Digitalmars-d
mailing list